From dbf7af068357b1deb837b468684c890f717ef3c0 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 28 Oct 2021 20:17:45 +0100 Subject: [PATCH 01/81] Indicator: Adds IndicatorTick --- Action.mqh | 18 +-- Condition.mqh | 20 +-- Indicator.mqh | 98 ++++++------- Indicator/IndicatorTick.h | 96 +++++++++++++ Indicator/tests/IndicatorTick.test.mq4 | 28 ++++ Indicator/tests/IndicatorTick.test.mq5 | 64 +++++++++ IndicatorBase.h | 189 ++----------------------- 7 files changed, 263 insertions(+), 250 deletions(-) create mode 100644 Indicator/IndicatorTick.h create mode 100644 Indicator/tests/IndicatorTick.test.mq4 create mode 100644 Indicator/tests/IndicatorTick.test.mq5 diff --git a/Action.mqh b/Action.mqh index 5ed379560..1e01b324d 100644 --- a/Action.mqh +++ b/Action.mqh @@ -139,14 +139,16 @@ class Action { break; #endif #ifdef INDICATOR_MQH - case ACTION_TYPE_INDICATOR: - if (Object::IsValid(_entry.obj)) { - _result = ((IndicatorBase *)_entry.obj).ExecuteAction((ENUM_INDICATOR_ACTION)_entry.action_id); - } else { - _result = false; - _entry.AddFlags(ACTION_ENTRY_FLAG_IS_INVALID); - } - break; + /* + case ACTION_TYPE_INDICATOR: + if (Object::IsValid(_entry.obj)) { + _result = ((IndicatorBase *)_entry.obj).ExecuteAction((ENUM_INDICATOR_ACTION)_entry.action_id); + } else { + _result = false; + _entry.AddFlags(ACTION_ENTRY_FLAG_IS_INVALID); + } + break; + */ #endif #ifdef STRATEGY_MQH case ACTION_TYPE_STRATEGY: diff --git a/Condition.mqh b/Condition.mqh index 915cbcd4e..862d20264 100644 --- a/Condition.mqh +++ b/Condition.mqh @@ -165,15 +165,17 @@ class Condition { } break; #ifdef INDICATOR_MQH - case COND_TYPE_INDICATOR: - if (Object::IsValid(_entry.obj)) { - _result = ((IndicatorBase *)_entry.obj).CheckCondition((ENUM_INDICATOR_CONDITION)_entry.cond_id, _entry.args); - } else { - // Static method not supported. - _result = false; - _entry.AddFlags(COND_ENTRY_FLAG_IS_INVALID); - } - break; + /* + case COND_TYPE_INDICATOR: + if (Object::IsValid(_entry.obj)) { + _result = ((IndicatorBase *)_entry.obj).CheckCondition((ENUM_INDICATOR_CONDITION)_entry.cond_id, + _entry.args); } else { + // Static method not supported. + _result = false; + _entry.AddFlags(COND_ENTRY_FLAG_IS_INVALID); + } + break; + */ #endif case COND_TYPE_MARKET: if (Object::IsValid(_entry.obj)) { diff --git a/Indicator.mqh b/Indicator.mqh index 3717c10aa..069497a53 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -56,9 +56,49 @@ class Chart; template class Indicator : public IndicatorBase { protected: - // Structs. + BufferStruct idata; TS iparams; + protected: + /* Protected methods */ + + bool Init() { + ArrayResize(value_storages, iparams.GetMaxModes()); + switch (iparams.GetDataSourceType()) { + case IDATA_BUILTIN: + break; + case IDATA_ICUSTOM: + break; + case IDATA_INDICATOR: + if (indi_src == NULL) { + // Indi_Price* _indi_price = Indi_Price::GetCached(GetSymbol(), GetTf(), iparams.GetShift()); + // SetDataSource(_indi_price, true, PRICE_OPEN); + } + break; + } + return InitDraw(); + } + + /** + * Initialize indicator data drawing on custom data. + */ + bool InitDraw() { + if (iparams.is_draw && !Object::IsValid(draw)) { + draw = new DrawIndicator(THIS_PTR); + draw.SetColorLine(iparams.indi_color); + } + return iparams.is_draw; + } + + /** + * Deinitialize drawing. + */ + void DeinitDraw() { + if (draw) { + delete draw; + } + } + public: /* Indicator enumerations */ @@ -115,47 +155,6 @@ class Indicator : public IndicatorBase { } } - /* Init methods */ - - bool Init() { - ArrayResize(value_storages, iparams.GetMaxModes()); - switch (iparams.GetDataSourceType()) { - case IDATA_BUILTIN: - break; - case IDATA_ICUSTOM: - break; - case IDATA_INDICATOR: - if (indi_src == NULL) { - // Indi_Price* _indi_price = Indi_Price::GetCached(GetSymbol(), GetTf(), iparams.GetShift()); - // SetDataSource(_indi_price, true, PRICE_OPEN); - } - break; - } - return InitDraw(); - } - - /** - * Initialize indicator data drawing on custom data. - */ - bool InitDraw() { - if (iparams.is_draw && !Object::IsValid(draw)) { - draw = new DrawIndicator(THIS_PTR); - draw.SetColorLine(iparams.indi_color); - } - return iparams.is_draw; - } - - /* Deinit methods */ - - /** - * Deinitialize drawing. - */ - void DeinitDraw() { - if (draw) { - delete draw; - } - } - /* Getters */ /** @@ -402,16 +401,12 @@ class Indicator : public IndicatorBase { */ virtual IndicatorBase* FetchDataSource(ENUM_INDICATOR_TYPE _id) { return NULL; } - /* Operator overloading methods */ + /* Getters */ /** - * Access indicator entry data using [] operator. + * Get pointer to data of indicator. */ - IndicatorDataEntry operator[](int _shift) { return GetEntry(_shift); } - IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _shift) { return GetEntry(_shift); } - IndicatorDataEntry operator[](datetime _dt) { return idata[_dt]; } - - /* Getters */ + BufferStruct* GetData() { return GetPointer(idata); } /** * Returns the highest bar's index (shift). @@ -613,11 +608,6 @@ class Indicator : public IndicatorBase { return _signals; } - /** - * Get pointer to data of indicator. - */ - BufferStruct* GetData() { return GetPointer(idata); } - /** * Get name of the indicator. */ diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h new file mode 100644 index 000000000..3fe26bdf9 --- /dev/null +++ b/Indicator/IndicatorTick.h @@ -0,0 +1,96 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Ignore processing of this file if already included. +#ifndef INDICATOR_TICK_MQH +#define INDICATOR_TICK_MQH + +// Includes. +#include "../IndicatorBase.h" +//#include "Array.mqh" +//#include "BufferStruct.mqh" +//#include "Chart.mqh" +//#include "DateTime.mqh" +//#include "DrawIndicator.mqh" +//#include "Indicator.define.h" +//#include "Indicator.enum.h" +//#include "Indicator.struct.cache.h" +//#include "Indicator.struct.h" +//#include "Indicator.struct.serialize.h" +//#include "Indicator.struct.signal.h" +//#include "IndicatorBase.h" +//#include "Math.h" +//#include "Object.mqh" +//#include "Refs.mqh" +//#include "Serializer.mqh" +//#include "SerializerCsv.mqh" +//#include "SerializerJson.mqh" +//#include "Storage/ValueStorage.h" +//#include "Storage/ValueStorage.indicator.h" +//#include "Storage/ValueStorage.native.h" + +/** + * Class to deal with tick indicators. + */ +// template +class IndicatorTick : public IndicatorBase { + protected: + BufferStruct tickdata; + + public: + /* Special methods */ + + /** + * Class constructor. + */ + IndicatorTick() {} + + /* Virtual method implementations */ + + /** + * Returns the indicator's data entry. + * + * @see: IndicatorDataEntry. + * + * @return + * Returns IndicatorDataEntry struct filled with indicator values. + */ + IndicatorDataEntry GetEntry(int _timestamp = 0) { + IndicatorDataEntry _entry = tickdata.GetByKey(_timestamp); + if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { + _entry.timestamp = _timestamp; + _entry.Resize(4); + _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); + for (int _mode = 0; _mode < (int)iparams.GetMaxModes(); _mode++) { + //_entry.values[_mode] = GetValue(_mode, _shift); / @todo + } + if (_entry.IsValid()) { + idata.Add(_entry, _bar_time); + } else { + _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); + } + } + return _entry; + } +}; + +#endif diff --git a/Indicator/tests/IndicatorTick.test.mq4 b/Indicator/tests/IndicatorTick.test.mq4 new file mode 100644 index 000000000..430e9d0e3 --- /dev/null +++ b/Indicator/tests/IndicatorTick.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorTick class. + */ + +// Includes. +#include "IndicatorTick.test.mq5" diff --git a/Indicator/tests/IndicatorTick.test.mq5 b/Indicator/tests/IndicatorTick.test.mq5 new file mode 100644 index 000000000..495154af3 --- /dev/null +++ b/Indicator/tests/IndicatorTick.test.mq5 @@ -0,0 +1,64 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorTick class. + */ + +// Includes. +#include "../../Test.mqh" +#include "../IndicatorTick.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + /* @fixme + // Initialize. + IndicatorParams iparams(INDI_NONE, TYPE_INT, 10); + Indicator *in = new Indicator(iparams, NULL); + // Check empty values. + assertTrueOrFail(in.GetBufferSize() == 10, "Wrong buffer size!"); + assertTrueOrFail(in.GetEmpty().double_value == 0.0, "Wrong empty double value!"); + assertTrueOrFail(in.GetEmpty().integer_value == 0, "Wrong empty integer value!"); + // Check dynamic allocation. + MqlParam entry; + entry.integer_value = 1; + for (uint i = 0; i < in.GetBufferSize() * 2; i++) { + in.AddValue(entry); + Print("Index ", i, ": Curr: ", in.GetValue(0).integer_value, "; Prev: ", in.GetValue(1).integer_value); + assertTrueOrFail(in.GetValue(0).integer_value == entry.integer_value, + StringFormat("Wrong latest value (%d <> %d)!", + in.GetValue(0).integer_value, + entry.integer_value)); + assertTrueOrFail(in.GetValue(1).integer_value == entry.integer_value - 1, + StringFormat("Wrong previous value (%d <> %d)!", + in.GetValue(1).integer_value, + entry.integer_value - 1)); + entry.integer_value++; + } + Print(in.ToString()); + // Clean up. + delete in; + */ + return (INIT_SUCCEEDED); +} diff --git a/IndicatorBase.h b/IndicatorBase.h index eed35dcdb..406bf8761 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -71,7 +71,6 @@ int IndicatorCounted(int _value = 0) { */ class IndicatorBase : public Chart { protected: - BufferStruct idata; DrawIndicator* draw; IndicatorState istate; void* mydata; @@ -99,11 +98,6 @@ class IndicatorBase : public Chart { /* Special methods */ - /** - * Class constructor. - */ - IndicatorBase() : indi_src(NULL) { is_fed = false; } - /** * Class constructor. */ @@ -112,7 +106,7 @@ class IndicatorBase : public Chart { /** * Class constructor. */ - IndicatorBase(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) : Chart(_tf, _symbol) { + IndicatorBase(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) : indi_src(NULL), Chart(_tf, _symbol) { is_fed = false; indi_src = NULL; } @@ -138,6 +132,15 @@ class IndicatorBase : public Chart { } } + /* Operator overloading methods */ + + /** + * Access indicator entry data using [] operator. + */ + // IndicatorDataEntry operator[](datetime _dt) { return GetEntry(_dt); } + IndicatorDataEntry operator[](int _index) { return GetEntry(_index); } + IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry(_index); } + /* Defines MQL backward compatible methods */ double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift) { @@ -406,15 +409,6 @@ class IndicatorBase : public Chart { */ IndicatorBase* GetDataSourceRaw() { return indi_src; } - /* Operator overloading methods */ - - /** - * Access indicator entry data using [] operator. - */ - IndicatorDataEntry operator[](int _shift) { return GetEntry(_shift); } - IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _shift) { return GetEntry(_shift); } - IndicatorDataEntry operator[](datetime _dt) { return idata[_dt]; } - /* Getters */ /** @@ -603,11 +597,6 @@ class IndicatorBase : public Chart { */ virtual ENUM_INDICATOR_TYPE GetType() { return INDI_NONE; } - /** - * Get pointer to data of indicator. - */ - BufferStruct* GetData() { return GetPointer(idata); } - /** * Get data type of indicator. */ @@ -665,88 +654,6 @@ class IndicatorBase : public Chart { */ void SetSymbol(string _symbol) { Set(CHART_PARAM_SYMBOL, _symbol); } - /* Conditions */ - - /** - * Checks for indicator condition. - * - * @param ENUM_INDICATOR_CONDITION _cond - * Indicator condition. - * @param MqlParam[] _args - * Condition arguments. - * @return - * Returns true when the condition is met. - */ - bool CheckCondition(ENUM_INDICATOR_CONDITION _cond, DataParamEntry& _args[]) { - switch (_cond) { - case INDI_COND_ENTRY_IS_MAX: - // @todo: Add arguments, check if the entry value is max. - return false; - case INDI_COND_ENTRY_IS_MIN: - // @todo: Add arguments, check if the entry value is min. - return false; - case INDI_COND_ENTRY_GT_AVG: - // @todo: Add arguments, check if... - // Indicator entry value is greater than average. - return false; - case INDI_COND_ENTRY_GT_MED: - // @todo: Add arguments, check if... - // Indicator entry value is greater than median. - return false; - case INDI_COND_ENTRY_LT_AVG: - // @todo: Add arguments, check if... - // Indicator entry value is lesser than average. - return false; - case INDI_COND_ENTRY_LT_MED: - // @todo: Add arguments, check if... - // Indicator entry value is lesser than median. - return false; - default: - GetLogger().Error(StringFormat("Invalid indicator condition: %s!", EnumToString(_cond), __FUNCTION_LINE__)); - return false; - } - } - bool CheckCondition(ENUM_INDICATOR_CONDITION _cond) { - ARRAY(DataParamEntry, _args); - return IndicatorBase::CheckCondition(_cond, _args); - } - - /** - * Execute Indicator action. - * - * @param ENUM_INDICATOR_ACTION _action - * Indicator action to execute. - * @param MqlParam _args - * Indicator action arguments. - * @return - * Returns true when the action has been executed successfully. - */ - virtual bool ExecuteAction(ENUM_INDICATOR_ACTION _action, DataParamEntry& _args[]) { - bool _result = true; - long _arg1 = ArraySize(_args) > 0 ? DataParamEntry::ToInteger(_args[0]) : WRONG_VALUE; - switch (_action) { - case INDI_ACTION_CLEAR_CACHE: - _arg1 = _arg1 > 0 ? _arg1 : TimeCurrent(); - idata.Clear(_arg1); - return true; - default: - GetLogger().Error(StringFormat("Invalid Indicator action: %s!", EnumToString(_action), __FUNCTION_LINE__)); - return false; - } - return _result; - } - bool ExecuteAction(ENUM_INDICATOR_ACTION _action) { - ARRAY(DataParamEntry, _args); - return ExecuteAction(_action, _args); - } - bool ExecuteAction(ENUM_INDICATOR_ACTION _action, long _arg1) { - ARRAY(DataParamEntry, _args); - DataParamEntry _param1 = _arg1; - ArrayPushObject(_args, _param1); - _args[0].integer_value = _arg1; - return ExecuteAction(_action, _args); - } - /* Other methods */ /** @@ -764,82 +671,6 @@ class IndicatorBase : public Chart { istate.is_changed = true; } - /** - * Checks whether indicator has a valid value for a given shift. - */ - virtual bool HasValidEntry(int _shift = 0) { - unsigned int position; - long bar_time = GetBarTime(_shift); - - if (idata.KeyExists(bar_time, position)) { - return idata.GetByPos(position).IsValid(); - } - - return false; - } - - /** - * Adds entry to the indicator's buffer. Invalid entry won't be added. - */ - bool AddEntry(IndicatorDataEntry& entry, int _shift = 0) { - if (!entry.IsValid()) return false; - - datetime timestamp = GetBarTime(_shift); - entry.timestamp = timestamp; - idata.Add(entry, timestamp); - - return true; - } - - /** - * Returns shift at which the last known valid entry exists for a given - * period (or from the start, when period is not specified). - */ - bool GetLastValidEntryShift(int& out_shift, int period = 0) { - out_shift = 0; - - while (true) { - if ((period != 0 && out_shift >= period) || !HasValidEntry(out_shift + 1)) - return out_shift > 0; // Current shift is always invalid. - - ++out_shift; - } - - return out_shift > 0; - } - - /** - * Returns shift at which the oldest known valid entry exists for a given - * period (or from the start, when period is not specified). - */ - bool GetOldestValidEntryShift(int& out_shift, int& out_num_valid, int shift = 0, int period = 0) { - bool found = false; - // Counting from previous up to previous - period. - for (out_shift = shift + 1; out_shift < shift + period + 1; ++out_shift) { - if (!HasValidEntry(out_shift)) { - --out_shift; - out_num_valid = out_shift - shift; - return found; - } else - found = true; - } - - --out_shift; - out_num_valid = out_shift - shift; - return found; - } - - /** - * Checks whether indicator has valid at least given number of last entries - * (counting from given shift or 0). - */ - bool HasAtLeastValidLastEntries(int period, int shift = 0) { - for (int i = 0; i < period; ++i) - if (!HasValidEntry(shift + i)) return false; - - return true; - } - virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = 0; ValueStorage* GetValueStorage(int _mode = 0) { From d829961595f7bf21604c67c30a514ba5dc189d36 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 13:22:57 +0000 Subject: [PATCH 02/81] Indicator: Fixes compilation errors --- Indicator.mqh | 9 +++++++-- IndicatorBase.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index bbdf08ef6..a995ae56d 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -70,7 +70,7 @@ class Indicator : public IndicatorBase { case IDATA_ICUSTOM: break; case IDATA_INDICATOR: - if (indi_src == NULL) { + if (indi_src.IsSet() == NULL) { // Indi_Price* _indi_price = Indi_Price::GetCached(GetSymbol(), GetTf(), iparams.GetShift()); // SetDataSource(_indi_price, true, PRICE_OPEN); } @@ -789,6 +789,7 @@ class Indicator : public IndicatorBase { * Returns shift at which the last known valid entry exists for a given * period (or from the start, when period is not specified). */ + /* bool GetLastValidEntryShift(int& out_shift, int period = 0) { out_shift = 0; @@ -800,12 +801,13 @@ class Indicator : public IndicatorBase { } return out_shift > 0; - } + }*/ /** * Returns shift at which the oldest known valid entry exists for a given * period (or from the start, when period is not specified). */ + /* bool GetOldestValidEntryShift(int& out_shift, int& out_num_valid, int shift = 0, int period = 0) { bool found = false; // Counting from previous up to previous - period. @@ -822,17 +824,20 @@ class Indicator : public IndicatorBase { out_num_valid = out_shift - shift; return found; } + */ /** * Checks whether indicator has valid at least given number of last entries * (counting from given shift or 0). */ + /* bool HasAtLeastValidLastEntries(int period, int shift = 0) { for (int i = 0; i < period; ++i) if (!HasValidEntry(shift + i)) return false; return true; } + */ ENUM_IDATA_VALUE_RANGE GetIDataValueRange() { return iparams.idvrange; } diff --git a/IndicatorBase.h b/IndicatorBase.h index 7e1753779..c7749d4a6 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -818,11 +818,13 @@ class IndicatorBase : public Chart { /** * Checks whether indicator has a valid value for a given shift. */ + /* virtual bool HasValidEntry(int _shift = 0) { unsigned int position; long bar_time = GetBarTime(_shift); return bar_time > 0 && idata.KeyExists(bar_time, position) ? idata.GetByPos(position).IsValid() : false; } + */ /** * Returns stored data in human-readable format. From e8554a1f27d5fcf001c33cfbf1f8d6cfbfcb566d Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 14:05:45 +0000 Subject: [PATCH 03/81] IndicatorTick: Fixes compilation errors --- Indicator/IndicatorTick.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 3fe26bdf9..21352c584 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -79,12 +79,12 @@ class IndicatorTick : public IndicatorBase { if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { _entry.timestamp = _timestamp; _entry.Resize(4); - _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); - for (int _mode = 0; _mode < (int)iparams.GetMaxModes(); _mode++) { - //_entry.values[_mode] = GetValue(_mode, _shift); / @todo - } + //_entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); + // for (int _mode = 0; _mode < (int)iparams.GetMaxModes(); _mode++) { + //_entry.values[_mode] = GetValue(_mode, _shift); / @todo + //} if (_entry.IsValid()) { - idata.Add(_entry, _bar_time); + // idata.Add(_entry, _bar_time); } else { _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); } From 53310b4889f9fe2f19aa1ee1b5e7c637e9a28a80 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 31 Oct 2021 18:34:18 +0000 Subject: [PATCH 04/81] Indicators: Adds Indi_TickMt --- .github/workflows/test-indicators-tick.yml | 65 ++++++++++++++++++ Indicator.enum.h | 5 +- Indicators/Tick/Indi_TickMt.mqh | 76 ++++++++++++++++++++++ Indicators/Tick/tests/Indi_TickMt.test.mq4 | 27 ++++++++ Indicators/Tick/tests/Indi_TickMt.test.mq5 | 60 +++++++++++++++++ 5 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test-indicators-tick.yml create mode 100644 Indicators/Tick/Indi_TickMt.mqh create mode 100644 Indicators/Tick/tests/Indi_TickMt.test.mq4 create mode 100644 Indicators/Tick/tests/Indi_TickMt.test.mq5 diff --git a/.github/workflows/test-indicators-tick.yml b/.github/workflows/test-indicators-tick.yml new file mode 100644 index 000000000..25eabe43c --- /dev/null +++ b/.github/workflows/test-indicators-tick.yml @@ -0,0 +1,65 @@ +--- +name: Test Indicators (Tick) + +# yamllint disable-line rule:truthy +on: + pull_request: + paths: + - 'Indicator**' + - 'Indicators/Tick/**' + - '.github/workflows/test-indicators-tick.yml' + push: + paths: + - 'Indicator**' + - 'Indicators/Tick/**' + - '.github/workflows/test-indicators-tick.yml' + +jobs: + + Compile: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Compile + uses: fx31337/mql-compile-action@master + with: + init-platform: true + path: 'Indicators/Tick/tests' + verbose: true + - name: Print compiled files + run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' + shell: powershell + - name: Upload artifacts (MQL4) + uses: actions/upload-artifact@v2 + with: + name: files-ex4 + path: '**/*.ex4' + - name: Upload artifacts (MQL5) + uses: actions/upload-artifact@v2 + with: + name: files-ex5 + path: '**/*.ex5' + + Indicators-Tests-MQL4: + defaults: + run: + shell: bash + working-directory: Indicators/tests + needs: Compile + runs-on: ubuntu-latest + strategy: + matrix: + test: + - Indi_Tick.test + steps: + - uses: actions/download-artifact@v2 + with: + name: files-ex4 + - name: Run ${{ matrix.test }} + uses: fx31337/mql-tester-action@master + with: + BtDays: 4-8 + BtMonths: 1 + BtYears: 2020 + TestExpert: ${{ matrix.test }} + timeout-minutes: 10 diff --git a/Indicator.enum.h b/Indicator.enum.h index 884f705a4..375064b34 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -96,7 +96,7 @@ enum ENUM_INDICATOR_TYPE { INDI_OSMA, // OsMA INDI_PATTERN, // Pattern Detector INDI_PIVOT, // Pivot Detector - INDI_PRICE, // Price Indicator + INDI_PRICE, // Price INDI_PRICE_CHANNEL, // Price Channel INDI_PRICE_FEEDER, // Indicator which returns prices from custom array INDI_PRICE_VOLUME_TREND, // Price and Volume Trend @@ -114,7 +114,8 @@ enum ENUM_INDICATOR_TYPE { INDI_STOCHASTIC, // Stochastic Oscillator INDI_SVE_BB, // SVE Bollinger Bands INDI_TEMA, // Triple Exponential Moving Average - INDI_TMA_TRUE, /// Triangular Moving Average True + INDI_TICK, // Tick + INDI_TMA_TRUE, // Triangular Moving Average True INDI_TRIX, // Triple Exponential Moving Averages Oscillator INDI_ULTIMATE_OSCILLATOR, // Ultimate Oscillator INDI_VIDYA, // Variable Index Dynamic Average diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh new file mode 100644 index 000000000..3bb9ee092 --- /dev/null +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -0,0 +1,76 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Includes. +#include "../../BufferStruct.mqh" +#include "../../Indicator.mqh" +#include "../../Storage/Objects.h" + +// Structs. +struct IndiTickMtParams : IndicatorParams { + string symbol; + // Struct constructor. + IndiTickMtParams(string _symbol = NULL, int _shift = 0) : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) { + SetShift(_shift); + }; + IndiTickMtParams(IndiTickMtParams &_params, ENUM_TIMEFRAMES _tf) { + THIS_REF = _params; + tf = _tf; + }; + // Getters. + string GetSymbol() { return symbol; } + // Setters. + void SetSymbol(string _symbol) { symbol = _symbol; } +}; + +/** + * Price Indicator. + */ +class Indi_TickMt : public Indicator { + public: + /** + * Class constructor. + */ + Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; + Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_TICK, _tf, _shift){}; + + /** + * Returns the indicator's value. + */ + virtual double GetValue(int _mode = 0, int _shift = 0) { + MqlTick _tick = SymbolInfoStatic::GetTick(_Symbol); + switch (_mode) { + case 0: + return _tick.ask; + case 1: + return _tick.bid; + case 2: +#ifdef __MQL4__ + return _tick.volume; +#else + return _tick.volume_real; +#endif + } + SetUserError(ERR_INVALID_PARAMETER); + return DBL_MAX; + } +}; diff --git a/Indicators/Tick/tests/Indi_TickMt.test.mq4 b/Indicators/Tick/tests/Indi_TickMt.test.mq4 new file mode 100644 index 000000000..091a1ba01 --- /dev/null +++ b/Indicators/Tick/tests/Indi_TickMt.test.mq4 @@ -0,0 +1,27 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of Indi_Tick indicator class. + */ + +#include "Indi_TickMt.test.mq5" diff --git a/Indicators/Tick/tests/Indi_TickMt.test.mq5 b/Indicators/Tick/tests/Indi_TickMt.test.mq5 new file mode 100644 index 000000000..4c9572767 --- /dev/null +++ b/Indicators/Tick/tests/Indi_TickMt.test.mq5 @@ -0,0 +1,60 @@ +//+------------------------------------------------------------------+ +//| 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 . + */ + +// Includes. +#include "../../../Test.mqh" +#include "../Indi_TickMt.mqh" + +/** + * @file + * Test functionality of Indi_TickMt indicator class. + */ + +Indi_TickMt indi(PERIOD_CURRENT); + +/** + * Implements Init event handler. + */ +int OnInit() { + bool _result = true; + assertTrueOrFail(indi.IsValid(), "Error on IsValid!"); + // assertTrueOrFail(indi.IsValidEntry(), "Error on IsValidEntry!"); + return (_result && _LastError == ERR_NO_ERROR ? INIT_SUCCEEDED : INIT_FAILED); +} + +/** + * Implements Tick event handler. + */ +void OnTick() { + static MqlTick _tick_last; + MqlTick _tick_new = SymbolInfoStatic::GetTick(_Symbol); + if (_tick_new.time % 60 < _tick_last.time % 60) { + // Process ticks each minute. + if (_tick_new.time % 3600 < _tick_last.time % 3600) { + // Print indicator values every hour. + Print(indi.ToString()); + if (indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { + assertTrueOrExit(indi.GetEntry().IsValid(), "Invalid entry!"); + } + } + } + _tick_last = _tick_new; +} From ad83367eb465821b3bdc8f033d3993611f8e023d Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 15:32:38 +0000 Subject: [PATCH 05/81] Tick/Indi_TickMt: Renames GetValue() to GetMixedValue() --- Indicators/Tick/Indi_TickMt.mqh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 3bb9ee092..46e5a44c6 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -56,7 +56,7 @@ class Indi_TickMt : public Indicator { /** * Returns the indicator's value. */ - virtual double GetValue(int _mode = 0, int _shift = 0) { + IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { MqlTick _tick = SymbolInfoStatic::GetTick(_Symbol); switch (_mode) { case 0: From 28ff4d40f41123cf20f905b3a977bba20358d68c Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 19:42:46 +0000 Subject: [PATCH 06/81] IndicatorTick: Implements tick fetching logic --- Indicator.mqh | 30 ++- Indicator/IndicatorTick.h | 207 ++++++++++++++++++--- IndicatorBase.h | 32 +--- Indicators/Tick/Indi_TickMt.mqh | 47 +++-- Indicators/Tick/tests/Indi_TickMt.test.mq5 | 5 +- Strategy.mqh | 3 +- 6 files changed, 242 insertions(+), 82 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index 94df3212e..c7def0976 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -519,6 +519,34 @@ class Indicator : public IndicatorBase { return median; } + /** + * Returns price corresponding to indicator value for a given shift and mode. + * + * Can be useful for calculating trailing stops based on the indicator. + * + * @return + * Returns price value of the corresponding indicator values. + */ + template + float GetValuePrice(int _shift = 0, int _mode = 0, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL) { + float _price = 0; + if (GetIDataValueRange() != IDATA_RANGE_PRICE) { + _price = (float)GetPrice(_ap, _shift); + } else if (GetIDataValueRange() == IDATA_RANGE_PRICE) { + // When indicator values are the actual prices. + T _values[4]; + if (!CopyValues(_values, 4, _shift, _mode)) { + // When values aren't valid, return 0. + return _price; + } + datetime _bar_time = GetBarTime(_shift); + float _value = 0; + BarOHLC _ohlc(_values, _bar_time); + _price = _ohlc.GetAppliedPrice(_ap); + } + return _price; + } + /** * Returns currently selected data source doing validation. */ @@ -839,7 +867,7 @@ class Indicator : public IndicatorBase { } */ - ENUM_IDATA_VALUE_RANGE GetIDataValueRange() { return iparams.idvrange; } + // ENUM_IDATA_VALUE_RANGE GetIDataValueRange() { return iparams.idvrange; } virtual void OnTick() { Chart::OnTick(); diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 21352c584..8f54219a9 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -26,35 +26,28 @@ // Includes. #include "../IndicatorBase.h" -//#include "Array.mqh" -//#include "BufferStruct.mqh" -//#include "Chart.mqh" -//#include "DateTime.mqh" -//#include "DrawIndicator.mqh" -//#include "Indicator.define.h" -//#include "Indicator.enum.h" -//#include "Indicator.struct.cache.h" -//#include "Indicator.struct.h" -//#include "Indicator.struct.serialize.h" -//#include "Indicator.struct.signal.h" -//#include "IndicatorBase.h" -//#include "Math.h" -//#include "Object.mqh" -//#include "Refs.mqh" -//#include "Serializer.mqh" -//#include "SerializerCsv.mqh" -//#include "SerializerJson.mqh" -//#include "Storage/ValueStorage.h" -//#include "Storage/ValueStorage.indicator.h" -//#include "Storage/ValueStorage.native.h" /** * Class to deal with tick indicators. */ -// template +template class IndicatorTick : public IndicatorBase { protected: - BufferStruct tickdata; + BufferStruct itdata; + TS itparams; + + protected: + /* Protected methods */ + + /** + * Initialize class. + * + * Called on constructor. + */ + void Init() { + itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); + itdata.SetOverflowListener(IndicatorTickOverflowListener, 10); + } public: /* Special methods */ @@ -62,7 +55,18 @@ class IndicatorTick : public IndicatorBase { /** * Class constructor. */ - IndicatorTick() {} + IndicatorTick(const TS& _itparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { + itparams = _itparams; + if (_indi_src != NULL) { + SetDataSource(_indi_src, _indi_mode); + } + Init(); + } + IndicatorTick(ENUM_INDICATOR_TYPE _itype, string _symbol, int _shift = 0, string _name = "") { + itparams.SetIndicatorType(_itype); + itparams.SetShift(_shift); + Init(); + } /* Virtual method implementations */ @@ -75,22 +79,163 @@ class IndicatorTick : public IndicatorBase { * Returns IndicatorDataEntry struct filled with indicator values. */ IndicatorDataEntry GetEntry(int _timestamp = 0) { - IndicatorDataEntry _entry = tickdata.GetByKey(_timestamp); + ResetLastError(); + IndicatorDataEntry _entry = itdata.GetByKey(_timestamp); if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { + _entry.Resize(itparams.GetMaxModes()); _entry.timestamp = _timestamp; - _entry.Resize(4); - //_entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); - // for (int _mode = 0; _mode < (int)iparams.GetMaxModes(); _mode++) { - //_entry.values[_mode] = GetValue(_mode, _shift); / @todo - //} + for (int _mode = 0; _mode < (int)itparams.GetMaxModes(); _mode++) { + switch (itparams.GetDataValueType()) { + case TYPE_BOOL: + case TYPE_CHAR: + case TYPE_INT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_LONG: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_UINT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_ULONG: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_DOUBLE: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_FLOAT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_STRING: + case TYPE_UCHAR: + default: + SetUserError(ERR_INVALID_PARAMETER); + break; + } + } + GetEntryAlter(_entry, _timestamp); + _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); if (_entry.IsValid()) { - // idata.Add(_entry, _bar_time); + itdata.Add(_entry, _timestamp); + istate.is_changed = false; + istate.is_ready = true; } else { _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); } } + if (_LastError != ERR_NO_ERROR) { + istate.is_ready = false; + ResetLastError(); + } return _entry; } + + /** + * Alters indicator's struct value. + * + * This method allows user to modify the struct entry before it's added to cache. + * This method is called on GetEntry() right after values are set. + */ + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = -1) { + _entry.AddFlags(_entry.GetDataTypeFlags(itparams.GetDataValueType())); + }; + + /** + * Returns the indicator's entry value for the given shift and mode. + * + * @see: DataParamEntry. + * + * @return + * Returns DataParamEntry struct filled with a single value. + */ + virtual DataParamEntry GetEntryValue(int _shift = -1, int _mode = 0) { + IndicatorDataEntry _entry = GetEntry(_shift >= 0 ? _shift : itparams.GetShift()); + DataParamEntry _value_entry; + return _value_entry; + } + + /** + * Function should return true if resize can be made, or false to overwrite current slot. + */ + static bool IndicatorTickOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { + switch (_reason) { + case DICT_OVERFLOW_REASON_FULL: + // We allow resize if dictionary size is less than 86400 slots. + return _size < 86400; + case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: + default: + // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. + break; + } + return false; + } + + /** + * Sets indicator data source. + */ + void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { + indi_src = _indi; + itparams.SetDataSource(-1, _input_mode); + } + + /* Virtual methods */ + + /** + * Returns a tick struct with price values. + * + * @see: MqlTick. + * + * @return + * Returns MqlTick struct with prices of the symbol. + */ + virtual MqlTick GetTick(int _timestamp = 0) { + IndicatorDataEntry _entry = GetEntry(_timestamp); + MqlTick _tick; + _tick.time = (datetime)_entry.GetTime(); + _tick.bid = _entry[0]; + _tick.ask = _entry[1]; + return _tick; + } + + /** + * Checks if indicator entry is valid. + * + * @return + * Returns true if entry is valid (has valid values), otherwise false. + */ + virtual bool IsValidEntry(IndicatorDataEntry& _entry) { + bool _result = true; + _result &= _entry.timestamp > 0; + _result &= _entry.GetSize() > 0; + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_REAL)) { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(DBL_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(FLT_MAX); + _result &= !_entry.HasValue(NULL); + } + } else { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_UNSIGNED)) { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(ULONG_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(UINT_MAX); + _result &= !_entry.HasValue(NULL); + } + } else { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(LONG_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(INT_MAX); + _result &= !_entry.HasValue(NULL); + } + } + } + return _result; + } }; #endif diff --git a/IndicatorBase.h b/IndicatorBase.h index ae3059e16..61f26a2a8 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -695,8 +695,6 @@ class IndicatorBase : public Chart { istate.is_changed = true; } - virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = 0; - ValueStorage* GetValueStorage(int _mode = 0) { if (value_storages[_mode] == NULL) { value_storages[_mode] = new IndicatorBufferValueStorage(THIS_PTR, _mode); @@ -713,34 +711,6 @@ class IndicatorBase : public Chart { virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) = NULL; - /** - * Returns price corresponding to indicator value for a given shift and mode. - * - * Can be useful for calculating trailing stops based on the indicator. - * - * @return - * Returns price value of the corresponding indicator values. - */ - template - float GetValuePrice(int _shift = 0, int _mode = 0, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL) { - float _price = 0; - if (GetIDataValueRange() != IDATA_RANGE_PRICE) { - _price = (float)GetPrice(_ap, _shift); - } else if (GetIDataValueRange() == IDATA_RANGE_PRICE) { - // When indicator values are the actual prices. - T _values[4]; - if (!CopyValues(_values, 4, _shift, _mode)) { - // When values aren't valid, return 0. - return _price; - } - datetime _bar_time = GetBarTime(_shift); - float _value = 0; - BarOHLC _ohlc(_values, _bar_time); - _price = _ohlc.GetAppliedPrice(_ap); - } - return _price; - } - /** * Returns values for a given shift. * @@ -798,6 +768,8 @@ class IndicatorBase : public Chart { */ virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = -1) = NULL; + // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = NULL; + /** * Returns the indicator's entry value. */ diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 46e5a44c6..ced489df0 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -21,9 +21,7 @@ */ // Includes. -#include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" -#include "../../Storage/Objects.h" +#include "../../Indicator/IndicatorTick.h" // Structs. struct IndiTickMtParams : IndicatorParams { @@ -45,32 +43,49 @@ struct IndiTickMtParams : IndicatorParams { /** * Price Indicator. */ -class Indi_TickMt : public Indicator { +class Indi_TickMt : public IndicatorTick { + protected: + MqlTick tick; + public: /** * Class constructor. */ - Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_TICK, _tf, _shift){}; + Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTick(_p, _indi_src){}; + Indi_TickMt(string _symbol, int _shift = 0) : IndicatorTick(INDI_TICK, _symbol, _shift){}; /** * Returns the indicator's value. */ IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { - MqlTick _tick = SymbolInfoStatic::GetTick(_Symbol); - switch (_mode) { - case 0: - return _tick.ask; - case 1: - return _tick.bid; - case 2: + if (_shift == 0) { + // Fetch a current prices of a specified symbol. + tick = SymbolInfoStatic::GetTick(itparams.GetSymbol()); + switch (_mode) { + case 0: + return tick.ask; + case 1: + return tick.bid; + case 2: #ifdef __MQL4__ - return _tick.volume; + return tick.volume; #else - return _tick.volume_real; + return tick.volume_real; #endif + } + SetUserError(ERR_INVALID_PARAMETER); } - SetUserError(ERR_INVALID_PARAMETER); return DBL_MAX; } + + /** + * Alters indicator's struct value. + * + * This method allows user to modify the struct entry before it's added to cache. + * This method is called on GetEntry() right after values are set. + */ + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + IndicatorTick::GetEntryAlter(_entry, _shift); + _entry.timestamp = _entry.timestamp > 0 ? _entry.timestamp : tick.time; + }; }; diff --git a/Indicators/Tick/tests/Indi_TickMt.test.mq5 b/Indicators/Tick/tests/Indi_TickMt.test.mq5 index 4c9572767..428552d78 100644 --- a/Indicators/Tick/tests/Indi_TickMt.test.mq5 +++ b/Indicators/Tick/tests/Indi_TickMt.test.mq5 @@ -28,7 +28,7 @@ * Test functionality of Indi_TickMt indicator class. */ -Indi_TickMt indi(PERIOD_CURRENT); +Indi_TickMt indi(_Symbol); /** * Implements Init event handler. @@ -36,7 +36,6 @@ Indi_TickMt indi(PERIOD_CURRENT); int OnInit() { bool _result = true; assertTrueOrFail(indi.IsValid(), "Error on IsValid!"); - // assertTrueOrFail(indi.IsValidEntry(), "Error on IsValidEntry!"); return (_result && _LastError == ERR_NO_ERROR ? INIT_SUCCEEDED : INIT_FAILED); } @@ -45,7 +44,7 @@ int OnInit() { */ void OnTick() { static MqlTick _tick_last; - MqlTick _tick_new = SymbolInfoStatic::GetTick(_Symbol); + MqlTick _tick_new = indi.GetTick(); if (_tick_new.time % 60 < _tick_last.time % 60) { // Process ticks each minute. if (_tick_new.time % 3600 < _tick_last.time % 3600) { diff --git a/Strategy.mqh b/Strategy.mqh index 50fe5c66c..a062b368d 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -1207,7 +1207,8 @@ class Strategy : public Object { _psm.SetChartParams(_chart.GetParams()); if (Object::IsValid(_indi)) { int _ishift = 12; // @todo: Make it dynamic or as variable. - float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); + float _value = 0.0f; // @todo + //float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); _value = _value + (float)Math::ChangeByPct(fabs(_value - _chart.GetCloseOffer(0)), _level) * _direction; _psm.SetIndicatorPriceValue(_value); /* From 565e493fb9b3c5e8a8cee42f30d9a6882d883504 Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 8 Nov 2021 14:11:23 +0000 Subject: [PATCH 07/81] Indicator: Renames GetMixedValue to GetEntryValue --- Indicator.mqh | 6 ++++-- IndicatorBase.h | 6 ++---- Indicators/Bitwise/Indi_Candle.mqh | 13 +++++++------ Indicators/Bitwise/Indi_Pattern.mqh | 13 +++++++------ Indicators/Indi_AC.mqh | 7 ++++--- Indicators/Indi_AD.mqh | 7 ++++--- Indicators/Indi_ADX.mqh | 8 +++++--- Indicators/Indi_ADXW.mqh | 7 ++++--- Indicators/Indi_AMA.mqh | 7 ++++--- Indicators/Indi_AO.mqh | 7 ++++--- Indicators/Indi_ASI.mqh | 7 ++++--- Indicators/Indi_ATR.mqh | 7 ++++--- Indicators/Indi_Alligator.mqh | 11 ++++++----- Indicators/Indi_AppliedPrice.mqh | 5 +++-- Indicators/Indi_BWMFI.mqh | 7 ++++--- Indicators/Indi_BWZT.mqh | 7 ++++--- Indicators/Indi_Bands.mqh | 9 +++++---- Indicators/Indi_BearsPower.mqh | 7 ++++--- Indicators/Indi_BullsPower.mqh | 7 ++++--- Indicators/Indi_CCI.mqh | 11 ++++++----- Indicators/Indi_CHO.mqh | 7 ++++--- Indicators/Indi_CHV.mqh | 7 ++++--- Indicators/Indi_ColorBars.mqh | 7 ++++--- Indicators/Indi_ColorCandlesDaily.mqh | 7 ++++--- Indicators/Indi_ColorLine.mqh | 7 ++++--- Indicators/Indi_CustomMovingAverage.mqh | 5 +++-- Indicators/Indi_DEMA.mqh | 9 +++++---- Indicators/Indi_DeMarker.mqh | 7 ++++--- Indicators/Indi_Demo.mqh | 7 ++++--- Indicators/Indi_DetrendedPrice.mqh | 7 ++++--- Indicators/Indi_Drawer.mqh | 7 ++++--- Indicators/Indi_Envelopes.mqh | 10 ++++++---- Indicators/Indi_Force.mqh | 7 ++++--- Indicators/Indi_FractalAdaptiveMA.mqh | 7 ++++--- Indicators/Indi_Fractals.mqh | 7 ++++--- Indicators/Indi_Gator.mqh | 7 ++++--- Indicators/Indi_HeikenAshi.mqh | 9 +++++---- Indicators/Indi_Ichimoku.mqh | 11 ++++++----- Indicators/Indi_Killzones.mqh | 5 +++-- Indicators/Indi_MA.mqh | 11 ++++++----- Indicators/Indi_MACD.mqh | 7 ++++--- Indicators/Indi_MFI.mqh | 9 +++++---- Indicators/Indi_MassIndex.mqh | 8 +++++--- Indicators/Indi_Momentum.mqh | 7 ++++--- Indicators/Indi_OBV.mqh | 9 +++++---- Indicators/Indi_OsMA.mqh | 7 ++++--- Indicators/Indi_Pivot.mqh | 5 ++++- Indicators/Indi_PriceChannel.mqh | 10 ++++------ Indicators/Indi_PriceFeeder.mqh | 7 ++++--- Indicators/Indi_PriceVolumeTrend.mqh | 7 ++++--- Indicators/Indi_RS.mqh | 5 +++-- Indicators/Indi_RSI.mqh | 10 ++++++---- Indicators/Indi_RVI.mqh | 7 ++++--- Indicators/Indi_RateOfChange.mqh | 7 ++++--- Indicators/Indi_SAR.mqh | 7 ++++--- Indicators/Indi_StdDev.mqh | 9 +++++---- Indicators/Indi_Stochastic.mqh | 7 ++++--- Indicators/Indi_TEMA.mqh | 7 ++++--- Indicators/Indi_TRIX.mqh | 9 +++++---- Indicators/Indi_UltimateOscillator.mqh | 7 ++++--- Indicators/Indi_VIDYA.mqh | 7 ++++--- Indicators/Indi_VROC.mqh | 7 ++++--- Indicators/Indi_Volumes.mqh | 7 ++++--- Indicators/Indi_WPR.mqh | 7 ++++--- Indicators/Indi_WilliamsAD.mqh | 7 ++++--- Indicators/Indi_ZigZag.mqh | 7 ++++--- Indicators/Indi_ZigZagColor.mqh | 11 +++++------ Indicators/OHLC/Indi_OHLC.mqh | 5 +++-- Indicators/Price/Indi_Price.mqh | 5 +++-- Indicators/Special/Indi_Math.mqh | 7 ++++--- Indicators/Tick/Indi_TickMt.mqh | 2 +- tests/DrawIndicatorTest.mq5 | 7 +------ tests/IndicatorsTest.mq5 | 2 +- 73 files changed, 303 insertions(+), 239 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index c7def0976..42955d2a9 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -1022,8 +1022,9 @@ class Indicator : public IndicatorBase { * @return * Returns DataParamEntry struct filled with a single value. */ - virtual DataParamEntry GetEntryValue(int _shift = -1, int _mode = 0) { - IndicatorDataEntry _entry = GetEntry(_shift >= 0 ? _shift : iparams.GetShift()); + /* + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + IndicatorDataEntry _entry = GetEntry(fmax(_shift, _shift >= 0 ? _shift : iparams.GetShift())); DataParamEntry _value_entry; switch (iparams.GetDataValueType()) { case TYPE_BOOL: @@ -1054,6 +1055,7 @@ class Indicator : public IndicatorBase { } return _value_entry; } + */ /** * Returns the indicator's value. diff --git a/IndicatorBase.h b/IndicatorBase.h index 61f26a2a8..d581a28b4 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -705,12 +705,10 @@ class IndicatorBase : public Chart { template T GetValue(int _shift = 0, int _mode = 0) { T _out; - GetMixedValue(_shift, _mode).Get(_out); + GetEntryValue(_shift, _mode).Get(_out); return _out; } - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) = NULL; - /** * Returns values for a given shift. * @@ -773,7 +771,7 @@ class IndicatorBase : public Chart { /** * Returns the indicator's entry value. */ - virtual DataParamEntry GetEntryValue(int _shift = -1, int _mode = 0) = NULL; + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) = NULL; /** * Returns indicator value for a given shift and mode. diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 0ff594c0d..a9b94aea1 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -66,14 +66,15 @@ class Indi_Candle : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); BarOHLC _ohlcs[1]; switch (iparams.idstype) { case IDATA_BUILTIN: // In this mode, price is fetched from chart. - _ohlcs[0] = Chart::GetOHLC(_shift); + _ohlcs[0] = Chart::GetOHLC(_ishift); break; case IDATA_INDICATOR: // In this mode, price is fetched from given indicator. Such indicator @@ -92,10 +93,10 @@ class Indi_Candle : public Indicator { break; } - _ohlcs[0].open = GetDataSource().GetValue(_shift, PRICE_OPEN); - _ohlcs[0].high = GetDataSource().GetValue(_shift, PRICE_HIGH); - _ohlcs[0].low = GetDataSource().GetValue(_shift, PRICE_LOW); - _ohlcs[0].close = GetDataSource().GetValue(_shift, PRICE_CLOSE); + _ohlcs[0].open = GetDataSource().GetValue(_ishift, PRICE_OPEN); + _ohlcs[0].high = GetDataSource().GetValue(_ishift, PRICE_HIGH); + _ohlcs[0].low = GetDataSource().GetValue(_ishift, PRICE_LOW); + _ohlcs[0].close = GetDataSource().GetValue(_ishift, PRICE_CLOSE); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index ed0d71f6d..f9e014ec0 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -57,15 +57,16 @@ class Indi_Pattern : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { int i; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); BarOHLC _ohlcs[8]; switch (iparams.idstype) { case IDATA_BUILTIN: // In this mode, price is fetched from chart. for (i = 0; i < iparams.GetMaxModes(); ++i) { - _ohlcs[i] = Chart::GetOHLC(_shift + i); + _ohlcs[i] = Chart::GetOHLC(_ishift + i); if (!_ohlcs[i].IsValid()) { // Return empty entry on invalid candles. return WRONG_VALUE; @@ -90,10 +91,10 @@ class Indi_Pattern : public Indicator { } for (i = 0; i < iparams.GetMaxModes(); ++i) { - _ohlcs[i].open = GetDataSource().GetValue(_shift + i, PRICE_OPEN); - _ohlcs[i].high = GetDataSource().GetValue(_shift + i, PRICE_HIGH); - _ohlcs[i].low = GetDataSource().GetValue(_shift + i, PRICE_LOW); - _ohlcs[i].close = GetDataSource().GetValue(_shift + i, PRICE_CLOSE); + _ohlcs[i].open = GetDataSource().GetValue(_ishift + i, PRICE_OPEN); + _ohlcs[i].high = GetDataSource().GetValue(_ishift + i, PRICE_HIGH); + _ohlcs[i].low = GetDataSource().GetValue(_ishift + i, PRICE_LOW); + _ohlcs[i].close = GetDataSource().GetValue(_ishift + i, PRICE_CLOSE); if (!_ohlcs[i].IsValid()) { // Return empty entry on invalid candles. return WRONG_VALUE; diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 5e9fb260e..be9fe709b 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -100,15 +100,16 @@ class Indi_AC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { IndicatorDataEntryValue _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_AC::iAC(GetSymbol(), GetTf(), _shift, THIS_PTR); + _value = Indi_AC::iAC(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index e2fcf2d5e..51ea677cf 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -101,15 +101,16 @@ class Indi_AD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_AD::iAD(GetSymbol(), GetTf(), _shift, THIS_PTR); + _value = Indi_AD::iAD(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index a403d961d..752805800 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -115,19 +115,21 @@ class Indi_ADX : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_ADX::iADX(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _mode, _shift, THIS_PTR); + _value = Indi_ADX::iADX(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); + break; } return _value; } diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index 6ac3565d7..efd22ce2e 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -215,16 +215,17 @@ class Indi_ADXW : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_ADXW::iADXWilder(GetSymbol(), GetTf(), GetPeriod(), _mode, _shift, THIS_PTR); + _value = Indi_ADXW::iADXWilder(GetSymbol(), GetTf(), GetPeriod(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index ceb65c602..58a8bee10 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -199,16 +199,17 @@ class Indi_AMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_AMA::iAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), - GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _shift, THIS_PTR); + GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - GetFastPeriod(), GetSlowPeriod(), GetAMAShift() /*]*/, _mode, _shift); + GetFastPeriod(), GetSlowPeriod(), GetAMAShift() /*]*/, _mode, _ishift); break; case IDATA_INDICATOR: diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index 6b494132e..a88552202 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -103,15 +103,16 @@ class Indi_AO : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_AO::iAO(GetSymbol(), GetTf(), _shift, _mode, THIS_PTR); + _value = Indi_AO::iAO(GetSymbol(), GetTf(), _ishift, _mode, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 953691830..2e0cf341b 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -155,18 +155,19 @@ class Indi_ASI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), - /*[*/ GetMaximumPriceChanging() /*]*/, 0, _shift); + /*[*/ GetMaximumPriceChanging() /*]*/, 0, _ishift); break; case IDATA_ONCALCULATE: { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(GetSymbol(), GetTf(), Util::MakeKey("Indi_ASI", GetMaximumPriceChanging())); _value = - iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, GetMaximumPriceChanging(), _mode, _shift, _cache); + iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, GetMaximumPriceChanging(), _mode, _ishift, _cache); break; } default: diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index e792d52a0..c74f1edd6 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -103,15 +103,16 @@ class Indi_ATR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_ATR::iATR(GetSymbol(), GetTf(), GetPeriod(), _shift, THIS_PTR); + _value = Indi_ATR::iATR(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index afccb5ff6..62b552df7 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -162,20 +162,21 @@ class Indi_Alligator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { + double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); #ifdef __MQL4__ if (_mode == 0) { // In MQL4 mode 0 should be treated as mode 1 as Alligator buffers starts from index 1. - return GetMixedValue((ENUM_ALLIGATOR_LINE)1, _shift); + return GetEntryValue((ENUM_ALLIGATOR_LINE)1, _ishift); } #endif - double _value = EMPTY_VALUE; switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Alligator::iAlligator(GetSymbol(), GetTf(), GetJawPeriod(), GetJawShift(), GetTeethPeriod(), GetTeethShift(), GetLipsPeriod(), GetLipsShift(), GetMAMethod(), - GetAppliedPrice(), (ENUM_ALLIGATOR_LINE)_mode, _shift, THIS_PTR); + GetAppliedPrice(), (ENUM_ALLIGATOR_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ @@ -183,7 +184,7 @@ class Indi_Alligator : public Indicator { GetLipsShift(), GetMAMethod(), GetAppliedPrice() /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index f4d875ddb..379596331 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -74,15 +74,16 @@ class Indi_AppliedPrice : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_INDICATOR: if (HasDataSource()) { // Future validation of indi_src will check if we set mode for source indicator // (e.g. for applied price of Indi_Price). iparams.SetDataSourceMode(GetAppliedPrice()); - _value = Indi_AppliedPrice::iAppliedPriceOnIndicator(GetDataSource(), GetAppliedPrice(), _shift); + _value = Indi_AppliedPrice::iAppliedPriceOnIndicator(GetDataSource(), GetAppliedPrice(), _ishift); } break; default: diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index a0216a332..cc8b55e08 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -114,16 +114,17 @@ class Indi_BWMFI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = BWMFI_BUFFER, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = BWMFI_BUFFER, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_BWMFI::iBWMFI(GetSymbol(), GetTf(), _shift, (ENUM_BWMFI_BUFFER)_mode, THIS_PTR); + _value = Indi_BWMFI::iBWMFI(GetSymbol(), GetTf(), _ishift, (ENUM_BWMFI_BUFFER)_mode, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ VOLUME_TICK /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index e03857648..65d7cb881 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -172,14 +172,15 @@ class Indi_BWZT : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_BWZT::iBWZT(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_BWZT::iBWZT(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index ee085c44b..0ff6a92e1 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -239,22 +239,23 @@ class Indi_Bands : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = BAND_BASE, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = BAND_BASE, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Bands::iBands(GetSymbol(), GetTf(), GetPeriod(), GetDeviation(), GetBandsShift(), - GetAppliedPrice(), (ENUM_BANDS_LINE)_mode, _shift, THIS_PTR); + GetAppliedPrice(), (ENUM_BANDS_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, /* [ */ GetPeriod(), - GetBandsShift(), GetDeviation(), GetAppliedPrice() /* ] */, _mode, _shift); + GetBandsShift(), GetDeviation(), GetAppliedPrice() /* ] */, _mode, _ishift); break; case IDATA_INDICATOR: // Calculating bands value from specified indicator. _value = Indi_Bands::iBandsOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), GetDeviation(), - GetBandsShift(), (ENUM_BANDS_LINE)_mode, _shift, THIS_PTR); + GetBandsShift(), (ENUM_BANDS_LINE)_mode, _ishift, THIS_PTR); break; } return _value; diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index d27567064..1b9721606 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -104,16 +104,17 @@ class Indi_BearsPower : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = _value = iBearsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _shift, THIS_PTR); + _value = _value = iBearsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index 9d0bbabe7..1741f8da7 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -104,16 +104,17 @@ class Indi_BullsPower : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = iBullsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _shift, THIS_PTR); + _value = iBullsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /**/ GetPeriod() /**/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index a0362f867..c32d4c191 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -145,25 +145,26 @@ class Indi_CCI : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; // @fixit Somehow shift isn't used neither in MT4 nor MT5. - _value = - Indi_CCI::iCCI(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _shift /* + iparams.shift*/, THIS_PTR); + _value = Indi_CCI::iCCI(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift /* + iparams.shift*/, + THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, /* [ */ GetPeriod(), - GetAppliedPrice() /* ] */, 0, _shift); + GetAppliedPrice() /* ] */, 0, _ishift); break; case IDATA_INDICATOR: ValidateSelectedDataSource(); // @fixit Somehow shift isn't used neither in MT4 nor MT5. _value = Indi_CCI::iCCIOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), GetDataSourceMode(), - _shift /* + iparams.shift*/); + _ishift /* + iparams.shift*/); break; } return _value; diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index 16fe50ea1..1cf24699e 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -166,16 +166,17 @@ class Indi_CHO : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_CHO::iChaikin(GetSymbol(), GetTf(), /*[*/ GetSlowMA(), GetFastMA(), GetSmoothMethod(), - GetInputVolume() /*]*/, _mode, _shift, THIS_PTR); + GetInputVolume() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetFastMA(), - GetSlowMA(), GetSmoothMethod(), GetInputVolume() /*]*/, 0, _shift); + GetSlowMA(), GetSmoothMethod(), GetInputVolume() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index ea7b34bc5..d3f97fd42 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -162,16 +162,17 @@ class Indi_CHV : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_CHV::iCHV(GetSymbol(), GetTf(), /*[*/ GetSmoothPeriod(), GetCHVPeriod(), GetSmoothMethod() /*]*/, - _mode, _shift, THIS_PTR); + _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetSmoothPeriod(), - GetCHVPeriod(), GetSmoothMethod() /*]*/, _mode, _shift); + GetCHVPeriod(), GetSmoothMethod() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index 056dcf04f..f89773c19 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -113,14 +113,15 @@ class Indi_ColorBars : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_ColorBars::iColorBars(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_ColorBars::iColorBars(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 31fc381c8..b8c4b851c 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -110,14 +110,15 @@ class Indi_ColorCandlesDaily : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_ColorCandlesDaily::iCCD(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_ColorCandlesDaily::iCCD(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ColorLine.mqh b/Indicators/Indi_ColorLine.mqh index 51ed0d7e9..d3dd60ed7 100644 --- a/Indicators/Indi_ColorLine.mqh +++ b/Indicators/Indi_ColorLine.mqh @@ -172,14 +172,15 @@ class Indi_ColorLine : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_ColorLine::iColorLine(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_ColorLine::iColorLine(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index 2c801b9bb..7d83ee7dc 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -67,12 +67,13 @@ class Indi_CustomMovingAverage : public Indicator /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetSmoothPeriod(), - GetSmoothShift(), GetSmoothMethod() /*]*/, 0, _shift); + GetSmoothShift(), GetSmoothMethod() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index 2d91c0934..420034607 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -166,26 +166,27 @@ class Indi_DEMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: // We're getting DEMA from Price indicator. istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_DEMA::iDEMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetAppliedPrice(), _shift, _mode, + _value = Indi_DEMA::iDEMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetAppliedPrice(), _ishift, _mode, GetPointer(this)); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, /*[*/ GetPeriod(), GetMAShift(), - GetAppliedPrice() /*]*/, _mode, _shift); + GetAppliedPrice() /*]*/, _mode, _ishift); break; case IDATA_INDICATOR: // Calculating DEMA value from specified indicator. _value = Indi_DEMA::iDEMAOnIndicator(GetCache(), GetDataSource(), GetDataSourceMode(), GetPeriod(), - GetMAShift(), _shift); + GetMAShift(), _ishift); break; } return _value; diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index 81a1e657e..98524dcdb 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -102,16 +102,17 @@ class Indi_DeMarker : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = _value = Indi_DeMarker::iDeMarker(GetSymbol(), GetTf(), GetPeriod(), _shift, THIS_PTR); + _value = _value = Indi_DeMarker::iDeMarker(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index 4f482b3b5..a5bf323d5 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -72,10 +72,11 @@ class Indi_Demo : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { - double _value = Indi_Demo::iDemo(GetSymbol(), GetTf(), _shift, THIS_PTR); + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + double _value = Indi_Demo::iDemo(GetSymbol(), GetTf(), _ishift, THIS_PTR); if (iparams.is_draw) { - draw.DrawLineTo(GetName(), GetBarTime(_shift), _value); + draw.DrawLineTo(GetName(), GetBarTime(_ishift), _value); } return _value; } diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index b2836d80c..b8c4fe1cd 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -116,16 +116,17 @@ class Indi_DetrendedPrice : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_DetrendedPrice::iDPO(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Drawer.mqh b/Indicators/Indi_Drawer.mqh index 85d74f98b..2fc3c2593 100644 --- a/Indicators/Indi_Drawer.mqh +++ b/Indicators/Indi_Drawer.mqh @@ -172,15 +172,16 @@ class Indi_Drawer : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_Drawer::iDrawer(GetSymbol(), GetTf(), _shift, THIS_PTR); + _value = Indi_Drawer::iDrawer(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; case IDATA_INDICATOR: - _value = Indi_Drawer::iDrawerOnIndicator(GetDataSource(), THIS_PTR, GetSymbol(), GetTf(), _shift); + _value = Indi_Drawer::iDrawerOnIndicator(GetDataSource(), THIS_PTR, GetSymbol(), GetTf(), _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index a3173c8a7..4761ab8ce 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -197,25 +197,27 @@ class Indi_Envelopes : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Envelopes::iEnvelopes(GetSymbol(), GetTf(), GetMAPeriod(), GetMAMethod(), GetMAShift(), - GetAppliedPrice(), GetDeviation(), _mode, _shift, THIS_PTR); + GetAppliedPrice(), GetDeviation(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /**/ GetMAPeriod(), - GetMAMethod(), GetMAShift(), GetAppliedPrice(), GetDeviation() /**/, _mode, _shift); + GetMAMethod(), GetMAShift(), GetAppliedPrice(), GetDeviation() /**/, _mode, _ishift); break; case IDATA_INDICATOR: _value = Indi_Envelopes::iEnvelopesOnIndicator(GetCache(), GetDataSource(), GetSymbol(), GetTf(), GetMAPeriod(), GetMAMethod(), GetDataSourceMode(), GetMAShift(), GetDeviation(), - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); + break; } return _value; } diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index a592684f0..9e047338b 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -117,17 +117,18 @@ class Indi_Force : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = - Indi_Force::iForce(GetSymbol(), GetTf(), GetPeriod(), GetMAMethod(), GetAppliedPrice(), _shift, THIS_PTR); + Indi_Force::iForce(GetSymbol(), GetTf(), GetPeriod(), GetMAMethod(), GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - GetMAMethod(), GetAppliedPrice(), VOLUME_TICK /*]*/, 0, _shift); + GetMAMethod(), GetAppliedPrice(), VOLUME_TICK /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 6f2d90889..7640170c0 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -134,16 +134,17 @@ class Indi_FrAMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_FrAMA::iFrAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFRAMAShift(), GetAppliedPrice() /*]*/, - _mode, _shift, THIS_PTR); + _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - GetFRAMAShift() /*]*/, 0, _shift); + GetFRAMAShift() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index c7c47158c..49d395311 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -102,15 +102,16 @@ class Indi_Fractals : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = _value = Indi_Fractals::iFractals(GetSymbol(), GetTf(), (ENUM_LO_UP_LINE)_mode, _shift, THIS_PTR); + _value = _value = Indi_Fractals::iFractals(GetSymbol(), GetTf(), (ENUM_LO_UP_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index 561b712f5..9dca4b882 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -169,14 +169,15 @@ class Indi_Gator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Gator::iGator(GetSymbol(), GetTf(), GetJawPeriod(), GetJawShift(), GetTeethPeriod(), GetTeethShift(), GetLipsPeriod(), GetLipsShift(), GetMAMethod(), GetAppliedPrice(), - (ENUM_GATOR_HISTOGRAM)_mode, _shift, THIS_PTR); + (ENUM_GATOR_HISTOGRAM)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /**/ @@ -184,7 +185,7 @@ class Indi_Gator : public Indicator { GetLipsShift(), GetMAMethod(), GetAppliedPrice() /**/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 30bbd751a..789478852 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -195,8 +195,9 @@ class Indi_HeikenAshi : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = HA_OPEN, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = HA_OPEN, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: #ifdef __MQL4__ @@ -216,15 +217,15 @@ class Indi_HeikenAshi : public Indicator { break; } #endif - _value = Indi_HeikenAshi::iHeikenAshi(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_HeikenAshi::iHeikenAshi(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; case IDATA_ICUSTOM_LEGACY: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_HeikenAshi::iCustomLegacyHeikenAshi(GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 504a7adc2..0f381d8d5 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -142,17 +142,18 @@ class Indi_Ichimoku : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Ichimoku::iIchimoku(GetSymbol(), GetTf(), GetTenkanSen(), GetKijunSen(), GetSenkouSpanB(), _mode, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetTenkanSen(), - GetKijunSen(), GetSenkouSpanB() /*]*/, _mode, _shift); + GetKijunSen(), GetSenkouSpanB() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); @@ -168,9 +169,9 @@ class Indi_Ichimoku : public Indicator { #ifdef __MQL4__ // In MQL4 value of LINE_TENKANSEN is 1 (not 0 as in MQL5), // so we are duplicating it. - _entry.values[0] = GetMixedValue(LINE_TENKANSEN, _shift); + _entry.values[0] = GetEntryValue(LINE_TENKANSEN, _shift); #endif - _entry.values[LINE_CHIKOUSPAN] = GetMixedValue(LINE_CHIKOUSPAN, _shift + 26); + _entry.values[LINE_CHIKOUSPAN] = GetEntryValue(LINE_CHIKOUSPAN, _shift + 26); } /** diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index c930ea5ab..70016b6db 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -106,9 +106,10 @@ class Indi_Killzones : public Indicator { /** * Returns the indicator's value. */ - IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { float _value = FLT_MAX; int _index = (int)_mode / 2; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: // Builtin mode not supported. @@ -118,7 +119,7 @@ class Indi_Killzones : public Indicator { ikt.Set(::TimeGMT()); if (ikt.CheckHours(_index)) { // Pass values to check for new highs or lows. - ikt.Update(_mode % 2 == 0 ? (float)GetHigh(_shift) : (float)GetLow(_shift), _index); + ikt.Update(_mode % 2 == 0 ? (float)GetHigh(_ishift) : (float)GetLow(_ishift), _index); } // Set a final value. _value = _mode % 2 == 0 ? ikt.GetHigh(_index) : ikt.GetLow(_index); diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 5dfbba5eb..d8ec96e68 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -627,23 +627,24 @@ class Indi_MA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_MA::iMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetMAMethod(), GetAppliedPrice(), _shift, - THIS_PTR); + _value = Indi_MA::iMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetMAMethod(), GetAppliedPrice(), + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, /* [ */ GetPeriod(), - GetMAShift(), GetMAMethod(), GetAppliedPrice() /* ] */, 0, _shift); + GetMAShift(), GetMAMethod(), GetAppliedPrice() /* ] */, 0, _ishift); break; case IDATA_INDICATOR: // Calculating MA value from specified indicator. _value = Indi_MA::iMAOnIndicator(GetCache(), GetDataSource(), GetDataSourceMode(), GetSymbol(), GetTf(), - GetPeriod(), GetMAShift(), GetMAMethod(), _shift); + GetPeriod(), GetMAShift(), GetMAMethod(), _ishift); break; } return _value; diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index a440c8ad4..64570f79b 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -114,18 +114,19 @@ class Indi_MACD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = LINE_MAIN, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_MACD::iMACD(GetSymbol(), GetTf(), GetEmaFastPeriod(), GetEmaSlowPeriod(), GetSignalPeriod(), - GetAppliedPrice(), (ENUM_SIGNAL_LINE)_mode, _shift, THIS_PTR); + GetAppliedPrice(), (ENUM_SIGNAL_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetEmaFastPeriod(), - GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice() /*]*/, _mode, _shift); + GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 0c27f09f6..902d6d08b 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -111,20 +111,21 @@ class Indi_MFI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; #ifdef __MQL4__ - _value = Indi_MFI::iMFI(GetSymbol(), GetTf(), GetPeriod(), _shift); + _value = Indi_MFI::iMFI(GetSymbol(), GetTf(), GetPeriod(), _ishift); #else // __MQL5__ - _value = Indi_MFI::iMFI(GetSymbol(), GetTf(), GetPeriod(), GetAppliedVolume(), _shift, THIS_PTR); + _value = Indi_MFI::iMFI(GetSymbol(), GetTf(), GetPeriod(), GetAppliedVolume(), _ishift, THIS_PTR); #endif break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - VOLUME_TICK /*]*/, 0, _shift); + VOLUME_TICK /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 8df1fb995..817b81cd8 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -153,19 +153,21 @@ class Indi_MassIndex : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_MassIndex::iMI(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetSecondPeriod(), GetSumPeriod() /*]*/, - _mode, _shift, THIS_PTR); + _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - GetSecondPeriod(), GetSumPeriod() /*]*/, _mode, _shift); + GetSecondPeriod(), GetSumPeriod() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); + break; } return _value; } diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 3a2c2cc32..5f4266dd0 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -141,18 +141,19 @@ class Indi_Momentum : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; // @fixit Somehow shift isn't used neither in MT4 nor MT5. - _value = Indi_Momentum::iMomentum(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), iparams.shift + _shift, + _value = Indi_Momentum::iMomentum(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), iparams.shift + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; case IDATA_INDICATOR: ValidateSelectedDataSource(); diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index 96ef284df..cefa485e9 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -118,20 +118,21 @@ class Indi_OBV : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; #ifdef __MQL4__ - _value = Indi_OBV::iOBV(GetSymbol(), GetTf(), GetAppliedPrice(), _shift); + _value = Indi_OBV::iOBV(GetSymbol(), GetTf(), GetAppliedPrice(), _ishift); #else // __MQL5__ - _value = Indi_OBV::iOBV(GetSymbol(), GetTf(), GetAppliedVolume(), _shift, THIS_PTR); + _value = Indi_OBV::iOBV(GetSymbol(), GetTf(), GetAppliedVolume(), _ishift, THIS_PTR); #endif break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ VOLUME_TICK /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index cd6c7a8e4..ac0a608a7 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -111,18 +111,19 @@ class Indi_OsMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_OsMA::iOsMA(GetSymbol(), GetTf(), GetEmaFastPeriod(), GetEmaSlowPeriod(), GetSignalPeriod(), - GetAppliedPrice(), _shift, THIS_PTR); + GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetEmaFastPeriod(), - GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice() /*]*/, 0, _shift); + GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 586e15f9c..fd4c7cf4d 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -100,7 +100,10 @@ class Indi_Pivot : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { return GetEntry(_shift)[_mode]; } + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + return GetEntry(_ishift)[_mode]; + } /** * Checks if indicator entry values are valid. diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index c5513fa72..0afc2392e 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -106,22 +106,20 @@ class Indi_PriceChannel : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { - ResetLastError(); + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_PriceChannel::iPriceChannel(GetSymbol(), GetTf(), GetPeriod(), _mode, _shift, THIS_PTR); + _value = Indi_PriceChannel::iPriceChannel(GetSymbol(), GetTf(), GetPeriod(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); } - istate.is_ready = _LastError == ERR_NO_ERROR; - istate.is_changed = false; return _value; } diff --git a/Indicators/Indi_PriceFeeder.mqh b/Indicators/Indi_PriceFeeder.mqh index e88ed67fc..c1d286d88 100644 --- a/Indicators/Indi_PriceFeeder.mqh +++ b/Indicators/Indi_PriceFeeder.mqh @@ -75,12 +75,13 @@ class Indi_PriceFeeder : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { int data_size = ArraySize(iparams.price_data); + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - if (_shift >= data_size || _shift < 0) return DBL_MIN; + if (_ishift >= data_size || _ishift < 0) return DBL_MIN; - double _value = iparams.price_data[data_size - _shift - 1]; + double _value = iparams.price_data[data_size - _ishift - 1]; return _value; } diff --git a/Indicators/Indi_PriceVolumeTrend.mqh b/Indicators/Indi_PriceVolumeTrend.mqh index f96c37dc5..17505eff1 100644 --- a/Indicators/Indi_PriceVolumeTrend.mqh +++ b/Indicators/Indi_PriceVolumeTrend.mqh @@ -121,16 +121,17 @@ class Indi_PriceVolumeTrend : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = - Indi_PriceVolumeTrend::iPVT(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _shift, THIS_PTR); + Indi_PriceVolumeTrend::iPVT(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), - /*[*/ GetAppliedVolume() /*]*/, 0, _shift); + /*[*/ GetAppliedVolume() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_RS.mqh b/Indicators/Indi_RS.mqh index 4e71dd17c..51c03ed8d 100644 --- a/Indicators/Indi_RS.mqh +++ b/Indicators/Indi_RS.mqh @@ -78,10 +78,11 @@ class Indi_RS : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_MATH: - return imath[_mode].Ptr().GetMixedValue(); + return imath[_mode].Ptr().GetEntryValue(); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index 895c13e54..41b7339a9 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -289,23 +289,25 @@ class Indi_RSI : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; double _res[]; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_RSI::iRSI(GetSymbol(), GetTf(), iparams.GetPeriod(), iparams.GetAppliedPrice(), _shift, THIS_PTR); + _value = + Indi_RSI::iRSI(GetSymbol(), GetTf(), iparams.GetPeriod(), iparams.GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, /* [ */ iparams.GetPeriod(), - iparams.GetAppliedPrice() /* ] */, 0, _shift); + iparams.GetAppliedPrice() /* ] */, 0, _ishift); Print(_value); break; case IDATA_INDICATOR: _value = Indi_RSI::iRSIOnIndicator(GetDataSource(), THIS_PTR, GetSymbol(), GetTf(), iparams.GetPeriod(), - iparams.GetAppliedPrice(), _shift); + iparams.GetAppliedPrice(), _ishift); break; } return _value; diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index 93967b54a..18402acad 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -103,16 +103,17 @@ class Indi_RVI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = LINE_MAIN, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_RVI::iRVI(GetSymbol(), GetTf(), GetPeriod(), (ENUM_SIGNAL_LINE)_mode, _shift, THIS_PTR); + _value = Indi_RVI::iRVI(GetSymbol(), GetTf(), GetPeriod(), (ENUM_SIGNAL_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - _mode, _shift); + _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index 438d4d6b3..076f4798a 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -110,16 +110,17 @@ class Indi_RateOfChange : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_RateOfChange::iROC(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_SAR.mqh b/Indicators/Indi_SAR.mqh index 570232fa0..2381c9cf3 100644 --- a/Indicators/Indi_SAR.mqh +++ b/Indicators/Indi_SAR.mqh @@ -102,16 +102,17 @@ class Indi_SAR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_SAR::iSAR(GetSymbol(), GetTf(), GetStep(), GetMax(), _shift, THIS_PTR); + _value = Indi_SAR::iSAR(GetSymbol(), GetTf(), GetStep(), GetMax(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetStep(), - GetMax() /*]*/, _mode, _shift); + GetMax() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 097771e74..4ef932b03 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -226,22 +226,23 @@ class Indi_StdDev : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_StdDev::iStdDev(GetSymbol(), GetTf(), GetMAPeriod(), GetMAShift(), GetMAMethod(), - GetAppliedPrice(), _shift, THIS_PTR); + GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), iparams.GetCustomIndicatorName(), /*[*/ GetMAPeriod(), GetMAShift(), GetMAMethod() /*]*/, 0, - _shift); + _ishift); break; case IDATA_INDICATOR: _value = Indi_StdDev::iStdDevOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetMAPeriod(), GetMAShift(), - GetAppliedPrice(), _shift, THIS_PTR); + GetAppliedPrice(), _ishift, THIS_PTR); break; } return _value; diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index 60628f69f..d60246205 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -119,17 +119,18 @@ class Indi_Stochastic : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = LINE_MAIN, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_Stochastic::iStochastic(GetSymbol(), GetTf(), GetKPeriod(), GetDPeriod(), GetSlowing(), - GetMAMethod(), GetPriceField(), _mode, _shift, THIS_PTR); + GetMAMethod(), GetPriceField(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetKPeriod(), - GetDPeriod(), GetSlowing() /*]*/, _mode, _shift); + GetDPeriod(), GetSlowing() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 9b1d201d4..3cc9e949b 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -126,16 +126,17 @@ class Indi_TEMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_TEMA::iTEMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetTEMAShift(), GetAppliedPrice() /*]*/, 0, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), - GetTEMAShift() /*]*/, 0, _shift); + GetTEMAShift() /*]*/, 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index b30899b8b..a8086bd27 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -127,16 +127,17 @@ class Indi_TRIX : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = - Indi_TRIX::iTriX(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, _shift, THIS_PTR); + _value = Indi_TRIX::iTriX(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, _ishift, + THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index 6a528dffa..7788bd77b 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -209,20 +209,21 @@ class Indi_UltimateOscillator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_UltimateOscillator::iUO(GetSymbol(), GetTf(), /*[*/ GetFastPeriod(), GetMiddlePeriod(), GetSlowPeriod(), GetFastK(), GetMiddleK(), GetSlowK() /*]*/, _mode, - _shift, THIS_PTR); + _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetFastPeriod(), GetMiddlePeriod(), GetSlowPeriod(), GetFastK(), GetMiddleK(), GetSlowK() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_VIDYA.mqh b/Indicators/Indi_VIDYA.mqh index 9e1d39bf0..a5647974c 100644 --- a/Indicators/Indi_VIDYA.mqh +++ b/Indicators/Indi_VIDYA.mqh @@ -147,19 +147,20 @@ class Indi_VIDYA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_VIDYA::iVIDyA(GetSymbol(), GetTf(), /*[*/ GetCMOPeriod(), GetMAPeriod(), GetVIDYAShift(), - GetAppliedPrice() /*]*/, 0, _shift, THIS_PTR); + GetAppliedPrice() /*]*/, 0, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetCMOPeriod(), GetMAPeriod(), GetVIDYAShift() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index 5ed32df45..2170fa831 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -130,16 +130,17 @@ class Indi_VROC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_VROC::iVROC(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _shift, + _value = Indi_VROC::iVROC(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), - /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _shift); + /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 29fea52dd..786f9fbbe 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -124,15 +124,16 @@ class Indi_Volumes : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_Volumes::iVolumes(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _shift, THIS_PTR); + _value = Indi_Volumes::iVolumes(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), - /*[*/ GetAppliedVolume() /*]*/, _mode, _shift); + /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index 1aad02998..8dcc258aa 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -101,16 +101,17 @@ class Indi_WPR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_WPR::iWPR(GetSymbol(), GetTf(), GetPeriod(), _shift, THIS_PTR); + _value = Indi_WPR::iWPR(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, - 0, _shift); + 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 03987b796..754cff808 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -124,14 +124,15 @@ class Indi_WilliamsAD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_WilliamsAD::iWAD(GetSymbol(), GetTf(), _mode, _shift, THIS_PTR); + _value = Indi_WilliamsAD::iWAD(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), 0, _shift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), 0, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 9c207f57e..94fa26e33 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -334,17 +334,18 @@ class Indi_ZigZag : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_ZigZag::iZigZag(GetSymbol(), GetTf(), GetDepth(), GetDeviation(), GetBackstep(), - (ENUM_ZIGZAG_LINE)_mode, _shift, THIS_PTR); + (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_ZigZag::iCustomZigZag(GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), GetDepth(), - GetDeviation(), GetBackstep(), (ENUM_ZIGZAG_LINE)_mode, _shift, THIS_PTR); + GetDeviation(), GetBackstep(), (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index 90c5ed66e..26489fd8f 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -268,23 +268,22 @@ class Indi_ZigZagColor : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { - ResetLastError(); + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_ZigZagColor::iZigZagColor(GetSymbol(), GetTf(), GetDepth(), GetDeviation(), GetBackstep(), - (ENUM_ZIGZAG_LINE)_mode, _shift, THIS_PTR); + (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), - /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, _mode, _shift); + /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); + break; } - istate.is_ready = _LastError == ERR_NO_ERROR; - istate.is_changed = false; return _value; } diff --git a/Indicators/OHLC/Indi_OHLC.mqh b/Indicators/OHLC/Indi_OHLC.mqh index cc1b5f926..7d7d26d93 100644 --- a/Indicators/OHLC/Indi_OHLC.mqh +++ b/Indicators/OHLC/Indi_OHLC.mqh @@ -60,7 +60,8 @@ class Indi_OHLC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); ENUM_APPLIED_PRICE _ap = PRICE_OPEN; switch (_mode) { case INDI_OHLC_CLOSE: @@ -76,7 +77,7 @@ class Indi_OHLC : public Indicator { _ap = PRICE_LOW; break; } - return ChartStatic::iPrice(_ap, GetSymbol(), GetTf(), _shift); + return ChartStatic::iPrice(_ap, GetSymbol(), GetTf(), _ishift); } /** diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index 4f155f775..74cd43db8 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -62,8 +62,9 @@ class Indi_Price : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { - return ChartStatic::iPrice(iparams.GetAppliedPrice(), GetSymbol(), GetTf(), _shift); + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + return ChartStatic::iPrice(iparams.GetAppliedPrice(), GetSymbol(), GetTf(), _ishift); } /** diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index dd11760b7..033377c04 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -93,8 +93,9 @@ class Indi_Math : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_INDICATOR: if (!indi_src.IsSet()) { @@ -112,12 +113,12 @@ class Indi_Math : public Indicator { case MATH_OP_MODE_BUILTIN: _value = Indi_Math::iMathOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetOpBuiltIn(), GetMode1(), GetMode2(), GetShift1(), - GetShift2() /*]*/, 0, _shift, &this); + GetShift2() /*]*/, 0, _ishift, &this); break; case MATH_OP_MODE_CUSTOM_FUNCTION: _value = Indi_Math::iMathOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetOpFunction(), GetMode1(), GetMode2(), GetShift1(), - GetShift2() /*]*/, 0, _shift, &this); + GetShift2() /*]*/, 0, _ishift, &this); break; } break; diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index ced489df0..a5d1b0e8e 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -57,7 +57,7 @@ class Indi_TickMt : public IndicatorTick { /** * Returns the indicator's value. */ - IndicatorDataEntryValue GetMixedValue(int _mode = 0, int _shift = 0) { + IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { if (_shift == 0) { // Fetch a current prices of a specified symbol. tick = SymbolInfoStatic::GetTick(itparams.GetSymbol()); diff --git a/tests/DrawIndicatorTest.mq5 b/tests/DrawIndicatorTest.mq5 index 19786332b..0ec2fc83b 100644 --- a/tests/DrawIndicatorTest.mq5 +++ b/tests/DrawIndicatorTest.mq5 @@ -151,14 +151,9 @@ bool InitIndicators() { * Print indicators. */ bool PrintIndicators(string _prefix = "") { + ResetLastError(); for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { IndicatorBase *_indi = iter.Value(); - MqlParam _value = _indi.GetEntryValue(); - if (GetLastError() == ERR_INDICATOR_DATA_NOT_FOUND || - GetLastError() == ERR_USER_ERROR_FIRST + ERR_USER_INVALID_BUFF_NUM) { - ResetLastError(); - continue; - } if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { PrintFormat("%s: %s: %s", _prefix, _indi.GetName(), _indi.ToString()); } diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 5c6ff58bf..3863538ae 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -557,7 +557,7 @@ bool PrintIndicators(string _prefix = "") { } string _indi_name = _indi.GetFullName(); - MqlParam _value = _indi.GetEntryValue(); + IndicatorDataEntryValue _value = _indi.GetEntryValue(); if (GetLastError() == ERR_INDICATOR_DATA_NOT_FOUND || GetLastError() == ERR_USER_ERROR_FIRST + ERR_USER_INVALID_BUFF_NUM) { ResetLastError(); From 42a6879cc6ed55683001ee14b46aa8ababb8e669 Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 8 Nov 2021 14:11:23 +0000 Subject: [PATCH 08/81] Indicator/IndicatorTick: Fixes return type --- Indicator/IndicatorTick.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 8f54219a9..602a27a6e 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -148,10 +148,9 @@ class IndicatorTick : public IndicatorBase { * @return * Returns DataParamEntry struct filled with a single value. */ - virtual DataParamEntry GetEntryValue(int _shift = -1, int _mode = 0) { - IndicatorDataEntry _entry = GetEntry(_shift >= 0 ? _shift : itparams.GetShift()); - DataParamEntry _value_entry; - return _value_entry; + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : itparams.GetShift(); + return GetEntry(_ishift)[_mode]; } /** From 16385fd779c4ecfed44db6be450b88c970abcce3 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 21:31:38 +0000 Subject: [PATCH 09/81] Indicator: Moving some methods from base class to main Indicator: Renames _shift to _index --- Indicator.mqh | 286 ++++++++++++++++++++++++++++++- Indicator/IndicatorTick.h | 2 +- IndicatorBase.h | 342 +++----------------------------------- 3 files changed, 311 insertions(+), 319 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index 42955d2a9..ae7c48e07 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -50,12 +50,39 @@ class Chart; #include "Storage/ValueStorage.indicator.h" #include "Storage/ValueStorage.native.h" +#ifndef __MQL4__ +// Defines global functions (for MQL4 backward compatibility). +bool IndicatorBuffers(int _count) { return Indicator::SetIndicatorBuffers(_count); } +int IndicatorCounted(int _value = 0) { + static int prev_calculated = 0; + // https://docs.mql4.com/customind/indicatorcounted + prev_calculated = _value > 0 ? _value : prev_calculated; + return prev_calculated; +} +#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. */ template class Indicator : public IndicatorBase { protected: + DrawIndicator* draw; BufferStruct idata; TS iparams; @@ -387,6 +414,127 @@ class Indicator : public IndicatorBase { */ virtual IndicatorBase* FetchDataSource(ENUM_INDICATOR_TYPE _id) { return NULL; } + /* State methods */ + + /** + * Checks for crossover. + * + * @return + * Returns true when values are crossing over, otherwise false. + */ + bool IsCrossover(int _shift1 = 0, int _shift2 = 1, int _mode1 = 0, int _mode2 = 0) { + double _curr_value1 = GetEntry(_shift1)[_mode1]; + double _prev_value1 = GetEntry(_shift2)[_mode1]; + double _curr_value2 = GetEntry(_shift1)[_mode2]; + double _prev_value2 = GetEntry(_shift2)[_mode2]; + return ((_curr_value1 > _prev_value1 && _curr_value2 < _prev_value2) || + (_prev_value1 > _curr_value1 && _prev_value2 < _curr_value2)); + } + + /** + * Checks if values are decreasing. + * + * @param int _rows + * Numbers of rows to check. + * @param int _mode + * Indicator index mode to check. + * @param int _shift + * Shift which is the final value to take into the account. + * + * @return + * Returns true when values are increasing. + */ + bool IsDecreasing(int _rows = 1, int _mode = 0, int _shift = 0) { + bool _result = true; + for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { + IndicatorDataEntry _entry_curr = GetEntry(i); + IndicatorDataEntry _entry_prev = GetEntry(i + 1); + _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] < _entry_prev[_mode]; + if (!_result) { + break; + } + } + return _result; + } + + /** + * Checks if value decreased by the given percentage value. + * + * @param int _pct + * Percentage value to use for comparison. + * @param int _mode + * Indicator index mode to use. + * @param int _shift + * Indicator value shift to use. + * @param int _count + * Count of bars to compare change backward. + * @param int _hundreds + * When true, use percentage in hundreds, otherwise 1 is 100%. + * + * @return + * Returns true when value increased. + */ + bool IsDecByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { + bool _result = true; + IndicatorDataEntry _v0 = GetEntry(_shift); + IndicatorDataEntry _v1 = GetEntry(_shift + _count); + _result &= _v0.IsValid() && _v1.IsValid(); + _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) < _pct; + return _result; + } + + /** + * Checks if values are increasing. + * + * @param int _rows + * Numbers of rows to check. + * @param int _mode + * Indicator index mode to check. + * @param int _shift + * Shift which is the final value to take into the account. + * + * @return + * Returns true when values are increasing. + */ + bool IsIncreasing(int _rows = 1, int _mode = 0, int _shift = 0) { + bool _result = true; + for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { + IndicatorDataEntry _entry_curr = GetEntry(i); + IndicatorDataEntry _entry_prev = GetEntry(i + 1); + _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] > _entry_prev[_mode]; + if (!_result) { + break; + } + } + return _result; + } + + /** + * Checks if value increased by the given percentage value. + * + * @param int _pct + * Percentage value to use for comparison. + * @param int _mode + * Indicator index mode to use. + * @param int _shift + * Indicator value shift to use. + * @param int _count + * Count of bars to compare change backward. + * @param int _hundreds + * When true, use percentage in hundreds, otherwise 1 is 100%. + * + * @return + * Returns true when value increased. + */ + bool IsIncByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { + bool _result = true; + IndicatorDataEntry _v0 = GetEntry(_shift); + IndicatorDataEntry _v1 = GetEntry(_shift + _count); + _result &= _v0.IsValid() && _v1.IsValid(); + _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) > _pct; + return _result; + } + /* Getters */ /** @@ -950,9 +1098,9 @@ class Indicator : public IndicatorBase { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - virtual IndicatorDataEntry GetEntry(int _shift = -1) { + virtual IndicatorDataEntry GetEntry(int _index = -1) { ResetLastError(); - int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + int _ishift = _index >= 0 ? _index : iparams.GetShift(); long _bar_time = GetBarTime(_ishift); IndicatorDataEntry _entry = idata.GetByKey(_bar_time); if (_bar_time > 0 && !_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { @@ -1023,7 +1171,7 @@ class Indicator : public IndicatorBase { * Returns DataParamEntry struct filled with a single value. */ /* - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, long _shift = -1) { IndicatorDataEntry _entry = GetEntry(fmax(_shift, _shift >= 0 ? _shift : iparams.GetShift())); DataParamEntry _value_entry; switch (iparams.GetDataValueType()) { @@ -1068,6 +1216,138 @@ class Indicator : public IndicatorBase { return EMPTY_VALUE; } */ + + /* Defines MQL backward compatible methods */ + + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, DUMMY); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _b, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a COMMA _b); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, int _mode, + int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, int _mode, + int _shift) { +#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); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, + int _mode, int _shift) { +#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); +#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, + int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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 + } }; #endif diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 602a27a6e..04c0fb3f7 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -136,7 +136,7 @@ class IndicatorTick : public IndicatorBase { * This method allows user to modify the struct entry before it's added to cache. * This method is called on GetEntry() right after values are set. */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { _entry.AddFlags(_entry.GetDataTypeFlags(itparams.GetDataValueType())); }; diff --git a/IndicatorBase.h b/IndicatorBase.h index d581a28b4..e13b9ed17 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -55,38 +55,11 @@ class Chart; #include "Storage/ValueStorage.native.h" #include "Util.h" -#ifndef __MQL4__ -// Defines global functions (for MQL4 backward compatibility). -bool IndicatorBuffers(int _count) { return Indicator::SetIndicatorBuffers(_count); } -int IndicatorCounted(int _value = 0) { - static int prev_calculated = 0; - // https://docs.mql4.com/customind/indicatorcounted - prev_calculated = _value > 0 ? _value : prev_calculated; - return prev_calculated; -} -#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. */ class IndicatorBase : public Chart { protected: - DrawIndicator* draw; IndicatorState istate; void* mydata; bool is_fed; // Whether calc_start_bar is already calculated. @@ -153,138 +126,6 @@ class IndicatorBase : public Chart { IndicatorDataEntry operator[](int _index) { return GetEntry(_index); } IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry(_index); } - /* Defines MQL backward compatible methods */ - - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, DUMMY); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _b, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a COMMA _b); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, int _mode, - int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, int _mode, - int _shift) { -#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); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, - int _mode, int _shift) { -#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); -#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, - int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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 - } - /* Buffer methods */ virtual string CacheKey() { return GetName(); } @@ -461,127 +302,6 @@ class IndicatorBase : public Chart { */ virtual int GetModeCount() { return 0; } - /* State methods */ - - /** - * Checks for crossover. - * - * @return - * Returns true when values are crossing over, otherwise false. - */ - bool IsCrossover(int _shift1 = 0, int _shift2 = 1, int _mode1 = 0, int _mode2 = 0) { - double _curr_value1 = GetEntry(_shift1)[_mode1]; - double _prev_value1 = GetEntry(_shift2)[_mode1]; - double _curr_value2 = GetEntry(_shift1)[_mode2]; - double _prev_value2 = GetEntry(_shift2)[_mode2]; - return ((_curr_value1 > _prev_value1 && _curr_value2 < _prev_value2) || - (_prev_value1 > _curr_value1 && _prev_value2 < _curr_value2)); - } - - /** - * Checks if values are decreasing. - * - * @param int _rows - * Numbers of rows to check. - * @param int _mode - * Indicator index mode to check. - * @param int _shift - * Shift which is the final value to take into the account. - * - * @return - * Returns true when values are increasing. - */ - bool IsDecreasing(int _rows = 1, int _mode = 0, int _shift = 0) { - bool _result = true; - for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { - IndicatorDataEntry _entry_curr = GetEntry(i); - IndicatorDataEntry _entry_prev = GetEntry(i + 1); - _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] < _entry_prev[_mode]; - if (!_result) { - break; - } - } - return _result; - } - - /** - * Checks if value decreased by the given percentage value. - * - * @param int _pct - * Percentage value to use for comparison. - * @param int _mode - * Indicator index mode to use. - * @param int _shift - * Indicator value shift to use. - * @param int _count - * Count of bars to compare change backward. - * @param int _hundreds - * When true, use percentage in hundreds, otherwise 1 is 100%. - * - * @return - * Returns true when value increased. - */ - bool IsDecByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { - bool _result = true; - IndicatorDataEntry _v0 = GetEntry(_shift); - IndicatorDataEntry _v1 = GetEntry(_shift + _count); - _result &= _v0.IsValid() && _v1.IsValid(); - _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) < _pct; - return _result; - } - - /** - * Checks if values are increasing. - * - * @param int _rows - * Numbers of rows to check. - * @param int _mode - * Indicator index mode to check. - * @param int _shift - * Shift which is the final value to take into the account. - * - * @return - * Returns true when values are increasing. - */ - bool IsIncreasing(int _rows = 1, int _mode = 0, int _shift = 0) { - bool _result = true; - for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { - IndicatorDataEntry _entry_curr = GetEntry(i); - IndicatorDataEntry _entry_prev = GetEntry(i + 1); - _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] > _entry_prev[_mode]; - if (!_result) { - break; - } - } - return _result; - } - - /** - * Checks if value increased by the given percentage value. - * - * @param int _pct - * Percentage value to use for comparison. - * @param int _mode - * Indicator index mode to use. - * @param int _shift - * Indicator value shift to use. - * @param int _count - * Count of bars to compare change backward. - * @param int _hundreds - * When true, use percentage in hundreds, otherwise 1 is 100%. - * - * @return - * Returns true when value increased. - */ - bool IsIncByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { - bool _result = true; - IndicatorDataEntry _v0 = GetEntry(_shift); - IndicatorDataEntry _v1 = GetEntry(_shift + _count); - _result &= _v0.IsValid() && _v1.IsValid(); - _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) > _pct; - return _result; - } - /* Getters */ /** @@ -596,26 +316,6 @@ class IndicatorBase : public Chart { int GetDataSourceMode() { return indi_src_mode; } - /** - * Gets indicator's symbol. - */ - string GetSymbol() { return Get(CHART_PARAM_SYMBOL); } - - /** - * Gets indicator's time-frame. - */ - ENUM_TIMEFRAMES GetTf() { return Get(CHART_PARAM_TF); } - - /** - * Gets indicator's signals. - * - * When indicator values are not valid, returns empty signals. - */ - virtual IndicatorSignal GetSignals(int _count = 3, int _shift = 0, int _mode1 = 0, int _mode2 = 0) { - IndicatorSignal _signal; - return _signal; - } - /** * Get indicator type. */ @@ -703,9 +403,9 @@ class IndicatorBase : public Chart { } template - T GetValue(int _shift = 0, int _mode = 0) { + T GetValue(int _index = 0, int _mode = 0) { T _out; - GetEntryValue(_shift, _mode).Get(_out); + GetEntryValue(_index, _mode).Get(_out); return _out; } @@ -715,8 +415,8 @@ class IndicatorBase : public Chart { * Note: Remember to check if shift exists by HasValidEntry(shift). */ template - bool GetValues(int _shift, T& _out1, T& _out2) { - IndicatorDataEntry _entry = GetEntry(_shift); + bool GetValues(int _index, T& _out1, T& _out2) { + IndicatorDataEntry _entry = GetEntry(_index); _out1 = _entry.values[0]; _out2 = _entry.values[1]; bool _result = GetLastError() != 4401; @@ -725,8 +425,8 @@ class IndicatorBase : public Chart { } template - bool GetValues(int _shift, T& _out1, T& _out2, T& _out3) { - IndicatorDataEntry _entry = GetEntry(_shift); + bool GetValues(int _index, T& _out1, T& _out2, T& _out3) { + IndicatorDataEntry _entry = GetEntry(_index); _out1 = _entry.values[0]; _out2 = _entry.values[1]; _out3 = _entry.values[2]; @@ -736,8 +436,8 @@ class IndicatorBase : public Chart { } template - bool GetValues(int _shift, T& _out1, T& _out2, T& _out3, T& _out4) { - IndicatorDataEntry _entry = GetEntry(_shift); + bool GetValues(int _index, T& _out1, T& _out2, T& _out3, T& _out4) { + IndicatorDataEntry _entry = GetEntry(_index); _out1 = _entry.values[0]; _out2 = _entry.values[1]; _out3 = _entry.values[2]; @@ -756,7 +456,7 @@ class IndicatorBase : public Chart { /** * Returns the indicator's struct value. */ - virtual IndicatorDataEntry GetEntry(int _shift = -1) = NULL; + virtual IndicatorDataEntry GetEntry(int _index = -1) = NULL; /** * Alters indicator's struct value. @@ -764,14 +464,14 @@ class IndicatorBase : public Chart { * This method allows user to modify the struct entry before it's added to cache. * This method is called on GetEntry() right after values are set. */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = -1) = NULL; + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _index = -1) = NULL; // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = NULL; /** * Returns the indicator's entry value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) = NULL; + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _index = -1) = NULL; /** * Returns indicator value for a given shift and mode. @@ -782,9 +482,9 @@ class IndicatorBase : public Chart { * Checks whether indicator has a valid value for a given shift. */ /* - virtual bool HasValidEntry(int _shift = 0) { + virtual bool HasValidEntry(int _index = 0) { unsigned int position; - long bar_time = GetBarTime(_shift); + long bar_time = GetBarTime(_index); return bar_time > 0 && idata.KeyExists(bar_time, position) ? idata.GetByPos(position).IsValid() : false; } */ @@ -810,8 +510,8 @@ class IndicatorBase : public Chart { /** * Returns the indicator's value in plain format. */ - virtual string ToString(int _shift = 0) { - IndicatorDataEntry _entry = GetEntry(_shift); + virtual string ToString(int _index = 0) { + IndicatorDataEntry _entry = GetEntry(_index); int _serializer_flags = SERIALIZER_FLAG_SKIP_HIDDEN | SERIALIZER_FLAG_INCLUDE_DEFAULT | SERIALIZER_FLAG_INCLUDE_DYNAMIC | SERIALIZER_FLAG_INCLUDE_FEATURE; @@ -846,6 +546,18 @@ class IndicatorBase : public Chart { // Assuming all entries are calculated (even if have invalid values). return _bars; } + + /* 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); } }; /** From 9f9c620ff57509bd159cbc07a0f5708ea7987246 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 23:05:56 +0000 Subject: [PATCH 10/81] IndicatorTick: Adds SetTick() --- Indicator/IndicatorTick.h | 46 +++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 04c0fb3f7..f97b2c43a 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -153,20 +153,24 @@ class IndicatorTick : public IndicatorBase { return GetEntry(_ishift)[_mode]; } + /* Setters */ + /** - * Function should return true if resize can be made, or false to overwrite current slot. + * Sets a tick struct with price values. + * + * @see: MqlTick. */ - static bool IndicatorTickOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { - switch (_reason) { - case DICT_OVERFLOW_REASON_FULL: - // We allow resize if dictionary size is less than 86400 slots. - return _size < 86400; - case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: - default: - // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. - break; - } - return false; + void SetTick(MqlTick& _tick, int _timestamp = 0) { + IndicatorDataEntry _entry(itparams.GetMaxModes()); + _entry.timestamp = _timestamp; + _entry.values[0] = _tick.bid; + _entry.values[1] = _tick.ask; +#ifdef __MQL4__ + _entry.values[2] = _tick.volume; +#else + _entry.values[2] = _tick.volume_real; +#endif + itdata.Add(_entry, _timestamp); } /** @@ -235,6 +239,24 @@ class IndicatorTick : public IndicatorBase { } return _result; } + + /* Callback methods */ + + /** + * Function should return true if resize can be made, or false to overwrite current slot. + */ + static bool IndicatorTickOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { + switch (_reason) { + case DICT_OVERFLOW_REASON_FULL: + // We allow resize if dictionary size is less than 86400 slots. + return _size < 86400; + case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: + default: + // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. + break; + } + return false; + } }; #endif From 4115a08b1265d303a922cd22457dbec4873d8ea1 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 23:28:13 +0000 Subject: [PATCH 11/81] IndicatorTick: Implements test --- .github/workflows/test-indicator.yml | 65 ++++++++++++++++++++++++++ Indicator/IndicatorTick.h | 2 +- Indicator/tests/IndicatorTick.test.mq5 | 52 ++++++++++----------- Indicators/Tick/Indi_TickMt.mqh | 1 + 4 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/test-indicator.yml diff --git a/.github/workflows/test-indicator.yml b/.github/workflows/test-indicator.yml new file mode 100644 index 000000000..0e0069949 --- /dev/null +++ b/.github/workflows/test-indicator.yml @@ -0,0 +1,65 @@ +--- +name: Test Indicator + +# yamllint disable-line rule:truthy +on: + pull_request: + paths: + - 'Indicator**' + - 'Indicator/**' + - '.github/workflows/test-indicator.yml' + push: + paths: + - 'Indicator**' + - 'Indicator/**' + - '.github/workflows/test-indicator.yml' + +jobs: + + Compile: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Compile + uses: fx31337/mql-compile-action@master + with: + init-platform: true + path: 'Indicator/tests' + verbose: true + - name: Print compiled files + run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' + shell: powershell + - name: Upload artifacts (MQL4) + uses: actions/upload-artifact@v2 + with: + name: files-ex4 + path: '**/*.ex4' + - name: Upload artifacts (MQL5) + uses: actions/upload-artifact@v2 + with: + name: files-ex5 + path: '**/*.ex5' + + Indicator-Tests-MQL4: + defaults: + run: + shell: bash + working-directory: Indicator/tests + needs: Compile + runs-on: ubuntu-latest + strategy: + matrix: + test: + - IndicatorTick.test + steps: + - uses: actions/download-artifact@v2 + with: + name: files-ex4 + - name: Run ${{ matrix.test }} + uses: fx31337/mql-tester-action@master + with: + BtDays: 4-8 + BtMonths: 1 + BtYears: 2020 + TestExpert: ${{ matrix.test }} + timeout-minutes: 10 diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index f97b2c43a..f64418f5c 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -160,7 +160,7 @@ class IndicatorTick : public IndicatorBase { * * @see: MqlTick. */ - void SetTick(MqlTick& _tick, int _timestamp = 0) { + void SetTick(MqlTick& _tick, long _timestamp = 0) { IndicatorDataEntry _entry(itparams.GetMaxModes()); _entry.timestamp = _timestamp; _entry.values[0] = _tick.bid; diff --git a/Indicator/tests/IndicatorTick.test.mq5 b/Indicator/tests/IndicatorTick.test.mq5 index 495154af3..07bab9c74 100644 --- a/Indicator/tests/IndicatorTick.test.mq5 +++ b/Indicator/tests/IndicatorTick.test.mq5 @@ -28,37 +28,35 @@ #include "../../Test.mqh" #include "../IndicatorTick.h" +// Structs. +struct IndicatorTickDummyParams : IndicatorParams { + IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} +}; + +/** + * Price Indicator. + */ +class IndicatorTickDummy : public IndicatorTick { + public: + IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { + SetSymbol(_symbol); + } +}; + /** * Implements OnInit(). */ int OnInit() { - /* @fixme - // Initialize. - IndicatorParams iparams(INDI_NONE, TYPE_INT, 10); - Indicator *in = new Indicator(iparams, NULL); - // Check empty values. - assertTrueOrFail(in.GetBufferSize() == 10, "Wrong buffer size!"); - assertTrueOrFail(in.GetEmpty().double_value == 0.0, "Wrong empty double value!"); - assertTrueOrFail(in.GetEmpty().integer_value == 0, "Wrong empty integer value!"); - // Check dynamic allocation. - MqlParam entry; - entry.integer_value = 1; - for (uint i = 0; i < in.GetBufferSize() * 2; i++) { - in.AddValue(entry); - Print("Index ", i, ": Curr: ", in.GetValue(0).integer_value, "; Prev: ", in.GetValue(1).integer_value); - assertTrueOrFail(in.GetValue(0).integer_value == entry.integer_value, - StringFormat("Wrong latest value (%d <> %d)!", - in.GetValue(0).integer_value, - entry.integer_value)); - assertTrueOrFail(in.GetValue(1).integer_value == entry.integer_value - 1, - StringFormat("Wrong previous value (%d <> %d)!", - in.GetValue(1).integer_value, - entry.integer_value - 1)); - entry.integer_value++; + IndicatorTickDummy _indi_tick(_Symbol); + long _time = 1; + for (double _price = 0.1; _price <= 2.0; _price += 0.1) { + MqlTick _tick; + _tick.time = (datetime)_time++; + _tick.ask = _price; + _tick.bid = _price; + _indi_tick.SetTick(_tick, _tick.time); } - Print(in.ToString()); - // Clean up. - delete in; - */ + // Print(_indi_tick.ToString()); return (INIT_SUCCEEDED); } diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index a5d1b0e8e..01d7dd2f7 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -29,6 +29,7 @@ struct IndiTickMtParams : IndicatorParams { // Struct constructor. IndiTickMtParams(string _symbol = NULL, int _shift = 0) : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) { SetShift(_shift); + SetSymbol(_symbol); }; IndiTickMtParams(IndiTickMtParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; From ef95f6f12734dde0c5e525fa496f285b981ec8c0 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 9 Nov 2021 23:40:25 +0000 Subject: [PATCH 12/81] Indicator: Adds IndicatorCandle class --- .github/workflows/test-indicator.yml | 1 + Indicator/IndicatorCandle.h | 223 +++++++++++++++++++++++ Indicator/tests/IndicatorCandle.test.mq4 | 28 +++ Indicator/tests/IndicatorCandle.test.mq5 | 37 ++++ 4 files changed, 289 insertions(+) create mode 100644 Indicator/IndicatorCandle.h create mode 100644 Indicator/tests/IndicatorCandle.test.mq4 create mode 100644 Indicator/tests/IndicatorCandle.test.mq5 diff --git a/.github/workflows/test-indicator.yml b/.github/workflows/test-indicator.yml index 0e0069949..66f4b9673 100644 --- a/.github/workflows/test-indicator.yml +++ b/.github/workflows/test-indicator.yml @@ -50,6 +50,7 @@ jobs: strategy: matrix: test: + - IndicatorCandle.test - IndicatorTick.test steps: - uses: actions/download-artifact@v2 diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h new file mode 100644 index 000000000..b2ff1abca --- /dev/null +++ b/Indicator/IndicatorCandle.h @@ -0,0 +1,223 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Ignore processing of this file if already included. +#ifndef INDICATOR_CANDLE_MQH +#define INDICATOR_CANDLE_MQH + +// Includes. +#include "../IndicatorBase.h" + +/** + * Class to deal with candle indicators. + */ +template +class IndicatorCandle : public IndicatorBase { + protected: + BufferStruct icdata; + TS icparams; + + protected: + /* Protected methods */ + + /** + * Initialize class. + * + * Called on constructor. + */ + void Init() { + itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); + itdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); + } + + public: + /* Special methods */ + + /** + * Class constructor. + */ + IndicatorCandle(const TS& _icdata, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { + icdata = _icdata; + if (_indi_src != NULL) { + SetDataSource(_indi_src, _indi_mode); + } + Init(); + } + IndicatorCandle(ENUM_INDICATOR_TYPE _itype, string _symbol, int _shift = 0, string _name = "") { + itparams.SetIndicatorType(_itype); + itparams.SetShift(_shift); + Init(); + } + + /* Virtual method implementations */ + + /** + * Returns the indicator's data entry. + * + * @see: IndicatorDataEntry. + * + * @return + * Returns IndicatorDataEntry struct filled with indicator values. + */ + IndicatorDataEntry GetEntry(int _timestamp = 0) { + ResetLastError(); + IndicatorDataEntry _entry = itdata.GetByKey(_timestamp); + if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { + _entry.Resize(itparams.GetMaxModes()); + _entry.timestamp = _timestamp; + for (int _mode = 0; _mode < (int)itparams.GetMaxModes(); _mode++) { + switch (itparams.GetDataValueType()) { + case TYPE_BOOL: + case TYPE_CHAR: + case TYPE_INT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_LONG: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_UINT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_ULONG: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_DOUBLE: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_FLOAT: + _entry.values[_mode] = GetValue(_mode, _timestamp); + break; + case TYPE_STRING: + case TYPE_UCHAR: + default: + SetUserError(ERR_INVALID_PARAMETER); + break; + } + } + GetEntryAlter(_entry, _timestamp); + _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); + if (_entry.IsValid()) { + itdata.Add(_entry, _timestamp); + istate.is_changed = false; + istate.is_ready = true; + } else { + _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); + } + } + if (_LastError != ERR_NO_ERROR) { + istate.is_ready = false; + ResetLastError(); + } + return _entry; + } + + /** + * Alters indicator's struct value. + * + * This method allows user to modify the struct entry before it's added to cache. + * This method is called on GetEntry() right after values are set. + */ + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { + _entry.AddFlags(_entry.GetDataTypeFlags(itparams.GetDataValueType())); + }; + + /** + * Returns the indicator's entry value for the given shift and mode. + * + * @see: DataParamEntry. + * + * @return + * Returns DataParamEntry struct filled with a single value. + */ + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + int _ishift = _shift >= 0 ? _shift : icparams.GetShift(); + return GetEntry(_ishift)[_mode]; + } + + /** + * Function should return true if resize can be made, or false to overwrite current slot. + */ + static bool IndicatorCandleOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) const { + switch (_reason) { + case DICT_OVERFLOW_REASON_FULL: + // We allow resize if dictionary size is less than 86400 slots. + return _size < 86400; + case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: + default: + // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. + break; + } + return false; + } + + /** + * Sets indicator data source. + */ + void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { + indi_src = _indi; + itparams.SetDataSource(-1, _input_mode); + } + + /* Virtual methods */ + + /** + * Checks if indicator entry is valid. + * + * @return + * Returns true if entry is valid (has valid values), otherwise false. + */ + virtual bool IsValidEntry(IndicatorDataEntry& _entry) { + bool _result = true; + _result &= _entry.timestamp > 0; + _result &= _entry.GetSize() > 0; + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_REAL)) { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(DBL_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(FLT_MAX); + _result &= !_entry.HasValue(NULL); + } + } else { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_UNSIGNED)) { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(ULONG_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(UINT_MAX); + _result &= !_entry.HasValue(NULL); + } + } else { + if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { + _result &= !_entry.HasValue(LONG_MAX); + _result &= !_entry.HasValue(NULL); + } else { + _result &= !_entry.HasValue(INT_MAX); + _result &= !_entry.HasValue(NULL); + } + } + } + return _result; + } +}; + +#endif diff --git a/Indicator/tests/IndicatorCandle.test.mq4 b/Indicator/tests/IndicatorCandle.test.mq4 new file mode 100644 index 000000000..93a0098bb --- /dev/null +++ b/Indicator/tests/IndicatorCandle.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorCandle class. + */ + +// Includes. +#include "IndicatorCandle.test.mq5" diff --git a/Indicator/tests/IndicatorCandle.test.mq5 b/Indicator/tests/IndicatorCandle.test.mq5 new file mode 100644 index 000000000..1d3f5c0d5 --- /dev/null +++ b/Indicator/tests/IndicatorCandle.test.mq5 @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorCandle class. + */ + +// Includes. +#include "../../Test.mqh" +#include "../IndicatorCandle.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + // @todo + return (INIT_SUCCEEDED); +} From cc388699f2df303e70393e333e53e691fc5b28b0 Mon Sep 17 00:00:00 2001 From: kenorb Date: Wed, 10 Nov 2021 00:20:24 +0000 Subject: [PATCH 13/81] Indicator: Adds IndicatorTf class --- .github/workflows/test-indicator.yml | 1 + Indicator/IndicatorCandle.h | 38 ++++++++------- Indicator/IndicatorTf.h | 69 ++++++++++++++++++++++++++++ Indicator/IndicatorTf.struct.h | 44 ++++++++++++++++++ Indicator/IndicatorTick.h | 9 +++- Indicator/tests/IndicatorTf.test.mq4 | 28 +++++++++++ Indicator/tests/IndicatorTf.test.mq5 | 37 +++++++++++++++ 7 files changed, 207 insertions(+), 19 deletions(-) create mode 100644 Indicator/IndicatorTf.h create mode 100644 Indicator/IndicatorTf.struct.h create mode 100644 Indicator/tests/IndicatorTf.test.mq4 create mode 100644 Indicator/tests/IndicatorTf.test.mq5 diff --git a/.github/workflows/test-indicator.yml b/.github/workflows/test-indicator.yml index 66f4b9673..87b68aa41 100644 --- a/.github/workflows/test-indicator.yml +++ b/.github/workflows/test-indicator.yml @@ -51,6 +51,7 @@ jobs: matrix: test: - IndicatorCandle.test + - IndicatorTf.test - IndicatorTick.test steps: - uses: actions/download-artifact@v2 diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index b2ff1abca..4b00672ac 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -21,8 +21,13 @@ */ // Ignore processing of this file if already included. -#ifndef INDICATOR_CANDLE_MQH -#define INDICATOR_CANDLE_MQH +#ifndef INDICATOR_CANDLE_H +#define INDICATOR_CANDLE_H + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif // Includes. #include "../IndicatorBase.h" @@ -45,8 +50,8 @@ class IndicatorCandle : public IndicatorBase { * Called on constructor. */ void Init() { - itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); - itdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); + icdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); + icdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); } public: @@ -55,16 +60,15 @@ class IndicatorCandle : public IndicatorBase { /** * Class constructor. */ - IndicatorCandle(const TS& _icdata, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { - icdata = _icdata; + IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) : icparams(_icparams) { if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); } Init(); } - IndicatorCandle(ENUM_INDICATOR_TYPE _itype, string _symbol, int _shift = 0, string _name = "") { - itparams.SetIndicatorType(_itype); - itparams.SetShift(_shift); + IndicatorCandle(ENUM_INDICATOR_TYPE _itype = INDI_CANDLE, int _shift = 0, string _name = "") { + icparams.SetIndicatorType(_itype); + icparams.SetShift(_shift); Init(); } @@ -80,12 +84,12 @@ class IndicatorCandle : public IndicatorBase { */ IndicatorDataEntry GetEntry(int _timestamp = 0) { ResetLastError(); - IndicatorDataEntry _entry = itdata.GetByKey(_timestamp); + IndicatorDataEntry _entry = icdata.GetByKey(_timestamp); if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - _entry.Resize(itparams.GetMaxModes()); + _entry.Resize(icparams.GetMaxModes()); _entry.timestamp = _timestamp; - for (int _mode = 0; _mode < (int)itparams.GetMaxModes(); _mode++) { - switch (itparams.GetDataValueType()) { + for (int _mode = 0; _mode < (int)icparams.GetMaxModes(); _mode++) { + switch (icparams.GetDataValueType()) { case TYPE_BOOL: case TYPE_CHAR: case TYPE_INT: @@ -116,7 +120,7 @@ class IndicatorCandle : public IndicatorBase { GetEntryAlter(_entry, _timestamp); _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); if (_entry.IsValid()) { - itdata.Add(_entry, _timestamp); + icdata.Add(_entry, _timestamp); istate.is_changed = false; istate.is_ready = true; } else { @@ -137,7 +141,7 @@ class IndicatorCandle : public IndicatorBase { * This method is called on GetEntry() right after values are set. */ virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { - _entry.AddFlags(_entry.GetDataTypeFlags(itparams.GetDataValueType())); + _entry.AddFlags(_entry.GetDataTypeFlags(icparams.GetDataValueType())); }; /** @@ -156,7 +160,7 @@ class IndicatorCandle : public IndicatorBase { /** * Function should return true if resize can be made, or false to overwrite current slot. */ - static bool IndicatorCandleOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) const { + static bool IndicatorCandleOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { switch (_reason) { case DICT_OVERFLOW_REASON_FULL: // We allow resize if dictionary size is less than 86400 slots. @@ -174,7 +178,7 @@ class IndicatorCandle : public IndicatorBase { */ void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { indi_src = _indi; - itparams.SetDataSource(-1, _input_mode); + icparams.SetDataSource(-1, _input_mode); } /* Virtual methods */ diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h new file mode 100644 index 000000000..b51828ce5 --- /dev/null +++ b/Indicator/IndicatorTf.h @@ -0,0 +1,69 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Ignore processing of this file if already included. +#ifndef INDICATOR_TF_H +#define INDICATOR_TF_H + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "IndicatorCandle.h" +#include "IndicatorTf.struct.h" + +/** + * Class to deal with candle indicators. + */ +class IndicatorTf : public IndicatorCandle { + protected: + /* Protected methods */ + + /** + * Initialize class. + * + * Called on constructor. + */ + void Init() {} + + public: + /* Special methods */ + + /** + * Class constructor. + */ + IndicatorTf(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { Init(); } + + /** + * Class constructor. + */ + IndicatorTf(ENUM_TIMEFRAMES_INDEX _tfi = 0) { Init(); } + + /** + * Class constructor with parameters. + */ + IndicatorTf(IndicatorTfParams &_params) : IndicatorCandle(_params) { Init(); } +}; + +#endif diff --git a/Indicator/IndicatorTf.struct.h b/Indicator/IndicatorTf.struct.h new file mode 100644 index 000000000..8e82a67bd --- /dev/null +++ b/Indicator/IndicatorTf.struct.h @@ -0,0 +1,44 @@ +//+------------------------------------------------------------------+ +//| 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 + * Includes IndicatorTf's structs. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +/* Structure for IndicatorTf class parameters. */ +struct IndicatorTfParams : IndicatorParams { + // Struct constructor. + IndicatorTfParams() {} + // Copy constructor. + IndicatorTfParams(const IndicatorTfParams &_params, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { + THIS_REF = _params; + if (_tf != PERIOD_CURRENT) { + tf.SetTf(_tf); + } + } +}; diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index f64418f5c..bf1487a03 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -21,8 +21,13 @@ */ // Ignore processing of this file if already included. -#ifndef INDICATOR_TICK_MQH -#define INDICATOR_TICK_MQH +#ifndef INDICATOR_TICK_H +#define INDICATOR_TICK_H + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif // Includes. #include "../IndicatorBase.h" diff --git a/Indicator/tests/IndicatorTf.test.mq4 b/Indicator/tests/IndicatorTf.test.mq4 new file mode 100644 index 000000000..360408073 --- /dev/null +++ b/Indicator/tests/IndicatorTf.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorTf class. + */ + +// Includes. +#include "IndicatorTf.test.mq5" diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 new file mode 100644 index 000000000..5c68d79a2 --- /dev/null +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of IndicatorTf class. + */ + +// Includes. +#include "../../Test.mqh" +#include "../IndicatorTf.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + // @todo + return (INIT_SUCCEEDED); +} From 4fbbc910c8aeabc05dbae335e5afa5abb39d5963 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 00:21:36 +0000 Subject: [PATCH 14/81] Indicator: Adds README.md with info about indicators --- Indicator/README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Indicator/README.md diff --git a/Indicator/README.md b/Indicator/README.md new file mode 100644 index 000000000..add1d2685 --- /dev/null +++ b/Indicator/README.md @@ -0,0 +1,54 @@ +# Indicator + +Indicator classes are intended for implementation of technical indicators. + +They can help with storing and accessing values and indicator parameters. + +## `IndicatorBase` + +An abstract class for all type of indicators (a base class). + +## `Indicator` + +An abstract class (subclass of `IndicatorBase`) to implement all type of indicators. + +It implements structure for storing input parameters +and buffer for accessing cached values by a given timestamp. + +## `IndicatorCandle` + +An abstract class (subclass of `IndicatorBase`) to implement candle indicators. + +It aims at managing prices by grouping them into OHLC chart candles. + +## `IndicatorRenko` + +(to be added) + +An abstract class (subclass of `IndicatorCandle`) to implement Renko indicators. + +It aims at managing prices by splitting them based solely on price movements. + +It can accept `IndicatorTick` as a data source. + +## `IndicatorTf` + +An abstract class (subclass of `IndicatorCandle`) +to implement timeframe indicators. + +It aims at storing prices by grouping them based on standardized time intervals +(e.g. M1, M2, M5). + +An instance has information about timeframe. + +Information about symbol can be accessed through the tick indicator. + +It can accept `IndicatorTick` as a data source. + +## `IndicatorTick` + +An abstract class (subclass of `IndicatorBase`) to implement tick indicators. + +It aims at managing bid and ask prices and can be used as data source. + +An instance has information about symbol, but it doesn't have timeframe. From 1c9a5eb05269e6077893f33058e6549078284605 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 13:08:54 +0000 Subject: [PATCH 15/81] Adds CandleOHLC and CandleTOHLC structs --- Candle.struct.h | 260 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 Candle.struct.h diff --git a/Candle.struct.h b/Candle.struct.h new file mode 100644 index 000000000..2fea358e6 --- /dev/null +++ b/Candle.struct.h @@ -0,0 +1,260 @@ +//+------------------------------------------------------------------+ +//| 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 + * Includes Bar's structs. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Forward class declaration. +class Serializer; + +// Includes. +#include "Bar.enum.h" +#include "Chart.enum.h" +#include "ISerializable.h" +#include "Serializer.enum.h" +#include "SerializerNode.enum.h" +#include "Std.h" + +/* Structore for storing OHLC values. */ +template +struct CandleOHLC +#ifndef __MQL__ + : public ISerializable +#endif +{ + T open, high, low, close; + CandleOHLC(T _open = 0, T _high = 0, T _low = 0, T _close = 0) : open(_open), high(_high), low(_low), close(_close) {} + CandleOHLC(ARRAY_REF(T, _prices)) { + int _size = ArraySize(_prices); + close = _prices[0]; + open = _prices[_size - 1]; + high = fmax(close, open); + low = fmin(close, open); + for (int i = 0; i < _size; i++) { + high = fmax(high, _prices[i]); + low = fmin(low, _prices[i]); + } + } + // Struct methods. + // Getters + bool GetPivots(ENUM_PP_TYPE _type, float &_pp, float &_r1, float &_r2, float &_r3, float &_r4, float &_s1, float &_s2, + float &_s3, float &_s4) { + float _range = GetRange(); + switch (_type) { + case PP_CAMARILLA: + // A set of eight very probable levels which resemble support and resistance values for a current trend. + _pp = GetPivot(); + _r1 = (float)(close + _range * 1.1 / 12); + _r2 = (float)(close + _range * 1.1 / 6); + _r3 = (float)(close + _range * 1.1 / 4); + _r4 = (float)(close + _range * 1.1 / 2); + _s1 = (float)(close - _range * 1.1 / 12); + _s2 = (float)(close - _range * 1.1 / 6); + _s3 = (float)(close - _range * 1.1 / 4); + _s4 = (float)(close - _range * 1.1 / 2); + break; + case PP_CLASSIC: + _pp = GetPivot(); + _r1 = (2 * _pp) - low; // R1 = (H - L) * 1.1 / 12 + C (1.0833) + _r2 = _pp + _range; // R2 = (H - L) * 1.1 / 6 + C (1.1666) + _r3 = _pp + _range * 2; // R3 = (H - L) * 1.1 / 4 + C (1.25) + _r4 = _pp + _range * 3; // R4 = (H - L) * 1.1 / 2 + C (1.5) + _s1 = (2 * _pp) - high; // S1 = C - (H - L) * 1.1 / 12 (1.0833) + _s2 = _pp - _range; // S2 = C - (H - L) * 1.1 / 6 (1.1666) + _s3 = _pp - _range * 2; // S3 = C - (H - L) * 1.1 / 4 (1.25) + _s4 = _pp - _range * 3; // S4 = C - (H - L) * 1.1 / 2 (1.5) + break; + case PP_FIBONACCI: + _pp = GetPivot(); + _r1 = (float)(_pp + 0.382 * _range); + _r2 = (float)(_pp + 0.618 * _range); + _r3 = _pp + _range; + _r4 = _r1 + _range; // ? + _s1 = (float)(_pp - 0.382 * _range); + _s2 = (float)(_pp - 0.618 * _range); + _s3 = _pp - _range; + _s4 = _s1 - _range; // ? + break; + case PP_FLOOR: + // Most basic and popular type of pivots used in Forex trading technical analysis. + _pp = GetPivot(); // Pivot (P) = (H + L + C) / 3 + _r1 = (2 * _pp) - low; // Resistance (R1) = (2 * P) - L + _r2 = _pp + _range; // R2 = P + H - L + _r3 = high + 2 * (_pp - low); // R3 = H + 2 * (P - L) + _r4 = _r3; + _s1 = (2 * _pp) - high; // Support (S1) = (2 * P) - H + _s2 = _pp - _range; // S2 = P - H + L + _s3 = low - 2 * (high - _pp); // S3 = L - 2 * (H - P) + _s4 = _s3; // ? + break; + case PP_TOM_DEMARK: + // Tom DeMark's pivot point (predicted lows and highs of the period). + _pp = GetPivotDeMark(); + _r1 = (2 * _pp) - low; // New High = X / 2 - L. + _r2 = _pp + _range; + _r3 = _r1 + _range; + _r4 = _r2 + _range; // ? + _s1 = (2 * _pp) - high; // New Low = X / 2 - H. + _s2 = _pp - _range; + _s3 = _s1 - _range; + _s4 = _s2 - _range; // ? + break; + case PP_WOODIE: + // Woodie's pivot point are giving more weight to the Close price of the previous period. + // They are similar to floor pivot points, but are calculated in a somewhat different way. + _pp = GetWeighted(); // Pivot (P) = (H + L + 2 * C) / 4 + _r1 = (2 * _pp) - low; // Resistance (R1) = (2 * P) - L + _r2 = _pp + _range; // R2 = P + H - L + _r3 = _r1 + _range; + _r4 = _r2 + _range; // ? + _s1 = (2 * _pp) - high; // Support (S1) = (2 * P) - H + _s2 = _pp - _range; // S2 = P - H + L + _s3 = _s1 - _range; + _s4 = _s2 - _range; // ? + break; + default: + break; + } + return _r4 > _r3 && _r3 > _r2 && _r2 > _r1 && _r1 > _pp && _pp > _s1 && _s1 > _s2 && _s2 > _s3 && _s3 > _s4; + } + float GetAppliedPrice(ENUM_APPLIED_PRICE _ap) const { + return CandleOHLC::GetAppliedPrice(_ap, open, high, low, close); + } + float GetBody() const { return close - open; } + float GetBodyAbs() const { return fabs(close - open); } + float GetBodyInPct(int _hundreds = 100) const { return GetRange() > 0 ? _hundreds / GetRange() * GetBodyAbs() : 0; } + float GetChangeInPct(int _hundreds = 100) const { return (close - open) / open * _hundreds; } + float GetClose() const { return close; } + float GetHigh() const { return high; } + float GetLow() const { return low; } + float GetMaxOC() const { return fmax(open, close); } + float GetMedian() const { return (high + low) / 2; } + float GetMinOC() const { return fmin(open, close); } + float GetOpen() const { return open; } + float GetPivot() const { return GetTypical(); } + float GetPivotDeMark() const { + // If Close < Open Then X = H + 2 * L + C + // If Close > Open Then X = 2 * H + L + C + // If Close = Open Then X = H + L + 2 * C + float _pp = open > close ? (high + (2 * low) + close) / 4 : ((2 * high) + low + close) / 4; + return open == close ? (high + low + (2 * close)) / 4 : _pp; + } + float GetPivotWithOpen() const { return (open + high + low + close) / 4; } + float GetPivotWithOpen(float _open) const { return (_open + high + low + close) / 4; } + float GetRange() const { return high - low; } + float GetRangeChangeInPct(int _hundreds = 100) const { + return _hundreds - (_hundreds / open * fabs(open - GetRange())); + } + float GetRangeInPips(float _ppp) const { return GetRange() / _ppp; } + float GetTypical() const { return (high + low + close) / 3; } + float GetWeighted() const { return (high + low + close + close) / 4; } + float GetWickMin() const { return fmin(GetWickLower(), GetWickUpper()); } + float GetWickLower() const { return GetMinOC() - low; } + float GetWickLowerInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickLower() : 0; } + float GetWickMax() const { return fmax(GetWickLower(), GetWickUpper()); } + float GetWickSum() const { return GetWickLower() + GetWickUpper(); } + float GetWickUpper() const { return high - GetMaxOC(); } + float GetWickUpperInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickUpper() : 0; } + short GetType() const { return IsBull() ? 1 : (IsBear() ? -1 : 0); } + void GetValues(ARRAY_REF(float, _out)) { + ArrayResize(_out, 4); + int _index = ArraySize(_out) - 4; + _out[_index++] = open; + _out[_index++] = high; + _out[_index++] = low; + _out[_index++] = close; + } + static T GetAppliedPrice(ENUM_APPLIED_PRICE _ap, T _o, T _h, T _l, T _c) { + switch (_ap) { + case PRICE_CLOSE: + return _c; + case PRICE_OPEN: + return _o; + case PRICE_HIGH: + return _h; + case PRICE_LOW: + return _l; + case PRICE_MEDIAN: + return (_h + _l) / 2; + case PRICE_TYPICAL: + return (_h + _l + _c) / 3; + case PRICE_WEIGHTED: + return (_h + _l + _c + _c) / 4; + default: + return _o; + } + } + // State checkers. + bool IsBear() const { return open > close; } + bool IsBull() const { return open < close; } + bool IsValid() const { return high >= low && fmin(open, close) > 0; } + // Serializers. + SerializerNodeType Serialize(Serializer &s); + // Converters. + string ToCSV() { return StringFormat("%g,%g,%g,%g", open, high, low, close); } +}; + +/* Structore for storing OHLC values with timestamp. */ +template +struct CandleTOHLC : CandleOHLC { + datetime time; + // Struct constructors. + CandleTOHLC(datetime _time = 0, T _open = 0, T _high = 0, T _low = 0, T _close = 0) + : time(_time), CandleOHLC(_open, _high, _low, _close) {} + // Getters. + datetime GetTime() { return time; } + // Serializers. + SerializerNodeType Serialize(Serializer &s); + // Converters. + string ToCSV() { return StringFormat("%d,%g,%g,%g,%g", time, open, high, low, close); } +}; + +#include "Serializer.mqh" + +/* Method to serialize CandleEntry structure. */ +template +SerializerNodeType CandleOHLC::Serialize(Serializer &s) { + // s.Pass(THIS_REF, "time", TimeToString(time)); + s.Pass(THIS_REF, "open", open, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "high", high, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "low", low, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "close", close, SERIALIZER_FIELD_FLAG_DYNAMIC); + return SerializerNodeObject; +} + +/* Method to serialize CandleEntry structure. */ +template +SerializerNodeType CandleTOHLC::Serialize(Serializer &s) { + s.Pass(THIS_REF, "time", time); + s.Pass(THIS_REF, "open", open, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "high", high, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "low", low, SERIALIZER_FIELD_FLAG_DYNAMIC); + s.Pass(THIS_REF, "close", close, SERIALIZER_FIELD_FLAG_DYNAMIC); + return SerializerNodeObject; +} From b7b85d629b3f99c0f828fc9335bfd6b49ac35a44 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 13:10:59 +0000 Subject: [PATCH 16/81] Buffer: Adds BufferCandle --- .github/workflows/test-buffer.yml | 60 +++++++++++++++++++++ Buffer/BufferCandle.h | 80 ++++++++++++++++++++++++++++ Buffer/tests/BufferCandle.test.mq4 | 28 ++++++++++ Buffer/tests/BufferCandle.test.mq5 | 59 +++++++++++++++++++++ Candle.struct.h | 85 ++++++++++++++---------------- 5 files changed, 267 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/test-buffer.yml create mode 100644 Buffer/BufferCandle.h create mode 100644 Buffer/tests/BufferCandle.test.mq4 create mode 100644 Buffer/tests/BufferCandle.test.mq5 diff --git a/.github/workflows/test-buffer.yml b/.github/workflows/test-buffer.yml new file mode 100644 index 000000000..7dc097568 --- /dev/null +++ b/.github/workflows/test-buffer.yml @@ -0,0 +1,60 @@ +--- +name: Test Buffer + +# yamllint disable-line rule:truthy +on: + pull_request: + paths: + - 'Buffer/**' + - '.github/workflows/test-buffer.yml' + push: + paths: + - 'Buffer/**' + - '.github/workflows/test-buffer.yml' + +jobs: + + Compile: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Compile + uses: fx31337/mql-compile-action@master + with: + init-platform: true + path: 'Buffer/tests' + verbose: true + - name: Print compiled files + run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' + shell: powershell + - name: Upload artifacts (MQL4) + uses: actions/upload-artifact@v2 + with: + name: files-ex4 + path: '**/*.ex4' + - name: Upload artifacts (MQL5) + uses: actions/upload-artifact@v2 + with: + name: files-ex5 + path: '**/*.ex5' + + Buffer-Tests-MQL4: + defaults: + run: + shell: bash + working-directory: Buffer/tests + needs: Compile + runs-on: ubuntu-latest + strategy: + matrix: + test: + - BufferCandle.test + steps: + - uses: actions/download-artifact@v2 + with: + name: files-ex4 + - name: Run ${{ matrix.test }} + uses: fx31337/mql-tester-action@master + with: + Script: ${{ matrix.test }} + timeout-minutes: 10 diff --git a/Buffer/BufferCandle.h b/Buffer/BufferCandle.h new file mode 100644 index 000000000..91586eb45 --- /dev/null +++ b/Buffer/BufferCandle.h @@ -0,0 +1,80 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Prevents processing this includes file for the second time. +#ifndef BUFFER_CANDLE_H +#define BUFFER_CANDLE_H + +// Includes. +#include "../BufferStruct.mqh" +#include "../Candle.struct.h" + +/** + * Class to store struct data. + */ +class BufferCandle : public BufferStruct> { + protected: + uint cache_limit; + + protected: + /* Protected methods */ + + /** + * Initialize class. + * + * Called on constructor. + */ + void Init() { SetOverflowListener(BufferCandleOverflowListener, 10); } + + public: + /* Constructors */ + + /** + * Constructor. + */ + BufferCandle() { Init(); } + BufferCandle(BufferCandle& _right) { + THIS_REF = _right; + Init(); + } + + /* Callback methods */ + + /** + * Function should return true if resize can be made, or false to overwrite current slot. + */ + static bool BufferCandleOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { + static int cache_limit = 86400; + switch (_reason) { + case DICT_OVERFLOW_REASON_FULL: + // We allow resize if dictionary size is less than 86400 slots. + return _size < cache_limit; + case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: + default: + // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. + break; + } + return false; + } +}; + +#endif // BUFFER_CANDLE_H diff --git a/Buffer/tests/BufferCandle.test.mq4 b/Buffer/tests/BufferCandle.test.mq4 new file mode 100644 index 000000000..fe6c0a00d --- /dev/null +++ b/Buffer/tests/BufferCandle.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of BufferCandle class. + */ + +// Includes. +#include "BufferCandle.test.mq5" diff --git a/Buffer/tests/BufferCandle.test.mq5 b/Buffer/tests/BufferCandle.test.mq5 new file mode 100644 index 000000000..61e66e616 --- /dev/null +++ b/Buffer/tests/BufferCandle.test.mq5 @@ -0,0 +1,59 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of BufferCandle class. + */ + +// Includes +#include "../../Test.mqh" +#include "../BufferCandle.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + BufferCandle buffer1; // 128 + CandleOHLC _ohlc_d; // 32 + CandleOHLC _ohlc_f; // 16 + CandleTOHLC _tohlc_d; // 32 + CandleTOHLC _tohlc_f; // 16 + // CandleEntry _centry_d; // 40 + // CandleEntry _centry_f; // 24 + Print("buffer1: ", sizeof(buffer1)); + Print("_ohlc_d: ", sizeof(_ohlc_d)); + Print("_ohlc_f: ", sizeof(_ohlc_f)); + Print("_tohlc_d: ", sizeof(_tohlc_d)); + Print("_tohlc_f: ", sizeof(_tohlc_f)); + // @todo + return (GetLastError() > 0 ? INIT_FAILED : INIT_SUCCEEDED); +} + +/** + * Implements OnTick(). + */ +void OnTick() {} + +/** + * Implements OnDeinit(). + */ +void OnDeinit(const int reason) {} diff --git a/Candle.struct.h b/Candle.struct.h index 2fea358e6..e713ceb22 100644 --- a/Candle.struct.h +++ b/Candle.struct.h @@ -63,21 +63,20 @@ struct CandleOHLC } // Struct methods. // Getters - bool GetPivots(ENUM_PP_TYPE _type, float &_pp, float &_r1, float &_r2, float &_r3, float &_r4, float &_s1, float &_s2, - float &_s3, float &_s4) { - float _range = GetRange(); + bool GetPivots(ENUM_PP_TYPE _type, T &_pp, T &_r1, T &_r2, T &_r3, T &_r4, T &_s1, T &_s2, T &_s3, T &_s4) { + T _range = GetRange(); switch (_type) { case PP_CAMARILLA: // A set of eight very probable levels which resemble support and resistance values for a current trend. _pp = GetPivot(); - _r1 = (float)(close + _range * 1.1 / 12); - _r2 = (float)(close + _range * 1.1 / 6); - _r3 = (float)(close + _range * 1.1 / 4); - _r4 = (float)(close + _range * 1.1 / 2); - _s1 = (float)(close - _range * 1.1 / 12); - _s2 = (float)(close - _range * 1.1 / 6); - _s3 = (float)(close - _range * 1.1 / 4); - _s4 = (float)(close - _range * 1.1 / 2); + _r1 = (T)(close + _range * 1.1 / 12); + _r2 = (T)(close + _range * 1.1 / 6); + _r3 = (T)(close + _range * 1.1 / 4); + _r4 = (T)(close + _range * 1.1 / 2); + _s1 = (T)(close - _range * 1.1 / 12); + _s2 = (T)(close - _range * 1.1 / 6); + _s3 = (T)(close - _range * 1.1 / 4); + _s4 = (T)(close - _range * 1.1 / 2); break; case PP_CLASSIC: _pp = GetPivot(); @@ -143,46 +142,42 @@ struct CandleOHLC } return _r4 > _r3 && _r3 > _r2 && _r2 > _r1 && _r1 > _pp && _pp > _s1 && _s1 > _s2 && _s2 > _s3 && _s3 > _s4; } - float GetAppliedPrice(ENUM_APPLIED_PRICE _ap) const { - return CandleOHLC::GetAppliedPrice(_ap, open, high, low, close); - } - float GetBody() const { return close - open; } - float GetBodyAbs() const { return fabs(close - open); } - float GetBodyInPct(int _hundreds = 100) const { return GetRange() > 0 ? _hundreds / GetRange() * GetBodyAbs() : 0; } - float GetChangeInPct(int _hundreds = 100) const { return (close - open) / open * _hundreds; } - float GetClose() const { return close; } - float GetHigh() const { return high; } - float GetLow() const { return low; } - float GetMaxOC() const { return fmax(open, close); } - float GetMedian() const { return (high + low) / 2; } - float GetMinOC() const { return fmin(open, close); } - float GetOpen() const { return open; } - float GetPivot() const { return GetTypical(); } - float GetPivotDeMark() const { + T GetAppliedPrice(ENUM_APPLIED_PRICE _ap) const { return CandleOHLC::GetAppliedPrice(_ap, open, high, low, close); } + T GetBody() const { return close - open; } + T GetBodyAbs() const { return fabs(close - open); } + T GetBodyInPct(int _hundreds = 100) const { return GetRange() > 0 ? _hundreds / GetRange() * GetBodyAbs() : 0; } + T GetChangeInPct(int _hundreds = 100) const { return (close - open) / open * _hundreds; } + T GetClose() const { return close; } + T GetHigh() const { return high; } + T GetLow() const { return low; } + T GetMaxOC() const { return fmax(open, close); } + T GetMedian() const { return (high + low) / 2; } + T GetMinOC() const { return fmin(open, close); } + T GetOpen() const { return open; } + T GetPivot() const { return GetTypical(); } + T GetPivotDeMark() const { // If Close < Open Then X = H + 2 * L + C // If Close > Open Then X = 2 * H + L + C // If Close = Open Then X = H + L + 2 * C - float _pp = open > close ? (high + (2 * low) + close) / 4 : ((2 * high) + low + close) / 4; + T _pp = open > close ? (high + (2 * low) + close) / 4 : ((2 * high) + low + close) / 4; return open == close ? (high + low + (2 * close)) / 4 : _pp; } - float GetPivotWithOpen() const { return (open + high + low + close) / 4; } - float GetPivotWithOpen(float _open) const { return (_open + high + low + close) / 4; } - float GetRange() const { return high - low; } - float GetRangeChangeInPct(int _hundreds = 100) const { - return _hundreds - (_hundreds / open * fabs(open - GetRange())); - } - float GetRangeInPips(float _ppp) const { return GetRange() / _ppp; } - float GetTypical() const { return (high + low + close) / 3; } - float GetWeighted() const { return (high + low + close + close) / 4; } - float GetWickMin() const { return fmin(GetWickLower(), GetWickUpper()); } - float GetWickLower() const { return GetMinOC() - low; } - float GetWickLowerInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickLower() : 0; } - float GetWickMax() const { return fmax(GetWickLower(), GetWickUpper()); } - float GetWickSum() const { return GetWickLower() + GetWickUpper(); } - float GetWickUpper() const { return high - GetMaxOC(); } - float GetWickUpperInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickUpper() : 0; } + T GetPivotWithOpen() const { return (open + high + low + close) / 4; } + T GetPivotWithOpen(float _open) const { return (_open + high + low + close) / 4; } + T GetRange() const { return high - low; } + T GetRangeChangeInPct(int _hundreds = 100) const { return _hundreds - (_hundreds / open * fabs(open - GetRange())); } + T GetRangeInPips(float _ppp) const { return GetRange() / _ppp; } + T GetTypical() const { return (high + low + close) / 3; } + T GetWeighted() const { return (high + low + close + close) / 4; } + T GetWickMin() const { return fmin(GetWickLower(), GetWickUpper()); } + T GetWickLower() const { return GetMinOC() - low; } + T GetWickLowerInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickLower() : 0; } + T GetWickMax() const { return fmax(GetWickLower(), GetWickUpper()); } + T GetWickSum() const { return GetWickLower() + GetWickUpper(); } + T GetWickUpper() const { return high - GetMaxOC(); } + T GetWickUpperInPct() const { return GetRange() > 0 ? 100 / GetRange() * GetWickUpper() : 0; } short GetType() const { return IsBull() ? 1 : (IsBear() ? -1 : 0); } - void GetValues(ARRAY_REF(float, _out)) { + void GetValues(ARRAY_REF(T, _out)) { ArrayResize(_out, 4); int _index = ArraySize(_out) - 4; _out[_index++] = open; From e80fd947af90c03c79303ea4efeea724948a8edb Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 18:03:36 +0000 Subject: [PATCH 17/81] Indicator/IndicatorCandle: Adds BufferCandle --- Buffer/BufferCandle.h | 3 ++- Buffer/tests/BufferCandle.test.mq5 | 2 +- Indicator/IndicatorCandle.h | 10 ++++++++-- Indicator/IndicatorTf.h | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Buffer/BufferCandle.h b/Buffer/BufferCandle.h index 91586eb45..ff77d7a08 100644 --- a/Buffer/BufferCandle.h +++ b/Buffer/BufferCandle.h @@ -31,7 +31,8 @@ /** * Class to store struct data. */ -class BufferCandle : public BufferStruct> { +template +class BufferCandle : public BufferStruct> { protected: uint cache_limit; diff --git a/Buffer/tests/BufferCandle.test.mq5 b/Buffer/tests/BufferCandle.test.mq5 index 61e66e616..ab76d8da8 100644 --- a/Buffer/tests/BufferCandle.test.mq5 +++ b/Buffer/tests/BufferCandle.test.mq5 @@ -32,7 +32,7 @@ * Implements OnInit(). */ int OnInit() { - BufferCandle buffer1; // 128 + BufferCandle buffer1; // 128 CandleOHLC _ohlc_d; // 32 CandleOHLC _ohlc_f; // 16 CandleTOHLC _tohlc_d; // 32 diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 4b00672ac..ff2e0fdc2 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -30,15 +30,16 @@ #endif // Includes. +#include "../Buffer/BufferCandle.h" #include "../IndicatorBase.h" /** * Class to deal with candle indicators. */ -template +template class IndicatorCandle : public IndicatorBase { protected: - BufferStruct icdata; + BufferCandle icdata; TS icparams; protected: @@ -84,6 +85,8 @@ class IndicatorCandle : public IndicatorBase { */ IndicatorDataEntry GetEntry(int _timestamp = 0) { ResetLastError(); + CandleOHLC _entry = icdata.GetByKey(_timestamp); + /* IndicatorDataEntry _entry = icdata.GetByKey(_timestamp); if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { _entry.Resize(icparams.GetMaxModes()); @@ -132,6 +135,9 @@ class IndicatorCandle : public IndicatorBase { ResetLastError(); } return _entry; + */ + IndicatorDataEntry _foo; + return _foo; } /** diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index b51828ce5..a64d22338 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -36,7 +36,7 @@ /** * Class to deal with candle indicators. */ -class IndicatorTf : public IndicatorCandle { +class IndicatorTf : public IndicatorCandle { protected: /* Protected methods */ @@ -63,7 +63,7 @@ class IndicatorTf : public IndicatorCandle { /** * Class constructor with parameters. */ - IndicatorTf(IndicatorTfParams &_params) : IndicatorCandle(_params) { Init(); } + IndicatorTf(IndicatorTfParams &_params) : IndicatorCandle(_params) { Init(); } }; #endif From 88e4c7191bacb1f25a524fdef57ec84ffb461a38 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 18:23:02 +0000 Subject: [PATCH 18/81] Renames MqlTick.h to MqlTick.struct.h --- MqlTick.h => MqlTick.struct.h | 0 SymbolInfo.struct.h | 2 +- SymbolInfo.struct.static.h | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename MqlTick.h => MqlTick.struct.h (100%) diff --git a/MqlTick.h b/MqlTick.struct.h similarity index 100% rename from MqlTick.h rename to MqlTick.struct.h diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index ba2dc565d..60f5b7b1a 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -32,7 +32,7 @@ // Includes. #include "ISerializable.h" -#include "MqlTick.h" +#include "MqlTick.struct.h" #include "SymbolInfo.struct.static.h" // Defines struct to store symbol data. diff --git a/SymbolInfo.struct.static.h b/SymbolInfo.struct.static.h index 7133cc0a3..a214f1ef5 100644 --- a/SymbolInfo.struct.static.h +++ b/SymbolInfo.struct.static.h @@ -26,7 +26,7 @@ #endif #include "MQL5.mqh" -#include "MqlTick.h" +#include "MqlTick.struct.h" #include "Std.h" /** From e0632a6262a4bac16ef8349495add24dbb9bdc4c Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 18:28:04 +0000 Subject: [PATCH 19/81] Renames MqlTick.struct.h to Tick.struct.h --- SymbolInfo.struct.h | 2 +- SymbolInfo.struct.static.h | 2 +- MqlTick.struct.h => Tick.struct.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename MqlTick.struct.h => Tick.struct.h (100%) diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index 60f5b7b1a..3e7b94bc8 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -32,7 +32,7 @@ // Includes. #include "ISerializable.h" -#include "MqlTick.struct.h" +#include "Tick.struct.h" #include "SymbolInfo.struct.static.h" // Defines struct to store symbol data. diff --git a/SymbolInfo.struct.static.h b/SymbolInfo.struct.static.h index a214f1ef5..f99368708 100644 --- a/SymbolInfo.struct.static.h +++ b/SymbolInfo.struct.static.h @@ -26,7 +26,7 @@ #endif #include "MQL5.mqh" -#include "MqlTick.struct.h" +#include "Tick.struct.h" #include "Std.h" /** diff --git a/MqlTick.struct.h b/Tick.struct.h similarity index 100% rename from MqlTick.struct.h rename to Tick.struct.h From f47bd0921993818ae33a946d4fcee2943623a871 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 18:48:50 +0000 Subject: [PATCH 20/81] Adds TickAB and TickTAB structs --- Tick.struct.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Tick.struct.h b/Tick.struct.h index 241e807b5..46d4efee4 100644 --- a/Tick.struct.h +++ b/Tick.struct.h @@ -29,6 +29,29 @@ #pragma once #endif +/** + * Structure for storing ask and bid prices of the symbol. + */ +template +struct TickAB { + T ask; // Current Ask price. + T bid; // Current Bid price. + // Struct constructors. + TickAB(T _ask = 0, T _bid = 0) : ask(_ask), bid(_bid) {} + TickAB(MqlTick &_tick) : ask(_tick.ask), bid(_tick.bid) {} +}; + +/** + * Structure for storing ask and bid prices of the symbol. + */ +template +struct TickTAB : TickAB { + datetime time; // Time of the last prices update. + // Struct constructors. + TickTAB(datetime _time = 0, T _ask = 0, T _bid = 0) : time(_time), TickAB(_ask, _bid) {} + TickAB(MqlTick &_tick) : time(_tick.time), TickAB(_tick.ask, _tick.bid) {} +}; + #ifndef __MQL__ /** * Structure for storing the latest prices of the symbol. From cb7ba0d4ea7f88e8d622255e9cb2112c9381059c Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 18:49:05 +0000 Subject: [PATCH 21/81] Buffer: Adds BufferTick --- .github/workflows/test-buffer.yml | 1 + Buffer/BufferCandle.h | 2 - Buffer/BufferTick.h | 79 ++++++++++++++++++++++++++ Buffer/tests/BufferTick.test.mq4 | 28 +++++++++ Buffer/tests/BufferTick.test.mq5 | 57 +++++++++++++++++++ Candle.struct.h | 1 + Indicator/IndicatorTick.h | 24 ++++---- Indicator/tests/IndicatorTick.test.mq5 | 2 +- Indicators/Tick/Indi_TickMt.mqh | 7 ++- Tick.struct.h | 4 +- 10 files changed, 184 insertions(+), 21 deletions(-) create mode 100644 Buffer/BufferTick.h create mode 100644 Buffer/tests/BufferTick.test.mq4 create mode 100644 Buffer/tests/BufferTick.test.mq5 diff --git a/.github/workflows/test-buffer.yml b/.github/workflows/test-buffer.yml index 7dc097568..bf23d92e7 100644 --- a/.github/workflows/test-buffer.yml +++ b/.github/workflows/test-buffer.yml @@ -49,6 +49,7 @@ jobs: matrix: test: - BufferCandle.test + - BufferTick.test steps: - uses: actions/download-artifact@v2 with: diff --git a/Buffer/BufferCandle.h b/Buffer/BufferCandle.h index ff77d7a08..b0230c58a 100644 --- a/Buffer/BufferCandle.h +++ b/Buffer/BufferCandle.h @@ -34,8 +34,6 @@ template class BufferCandle : public BufferStruct> { protected: - uint cache_limit; - protected: /* Protected methods */ diff --git a/Buffer/BufferTick.h b/Buffer/BufferTick.h new file mode 100644 index 000000000..8e6ac9093 --- /dev/null +++ b/Buffer/BufferTick.h @@ -0,0 +1,79 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +// Prevents processing this includes file for the second time. +#ifndef BUFFER_TICK_H +#define BUFFER_TICK_H + +// Includes. +#include "../BufferStruct.mqh" +#include "../Tick.struct.h" + +/** + * Class to store struct data. + */ +template +class BufferTick : public BufferStruct> { + protected: + protected: + /* Protected methods */ + + /** + * Initialize class. + * + * Called on constructor. + */ + void Init() { SetOverflowListener(BufferTickOverflowListener, 10); } + + public: + /* Constructors */ + + /** + * Constructor. + */ + BufferTick() { Init(); } + BufferTick(BufferTick& _right) { + THIS_REF = _right; + Init(); + } + + /* Callback methods */ + + /** + * Function should return true if resize can be made, or false to overwrite current slot. + */ + static bool BufferTickOverflowListener(ENUM_DICT_OVERFLOW_REASON _reason, int _size, int _num_conflicts) { + static int cache_limit = 86400; + switch (_reason) { + case DICT_OVERFLOW_REASON_FULL: + // We allow resize if dictionary size is less than 86400 slots. + return _size < cache_limit; + case DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS: + default: + // When there is too many conflicts, we just reject doing resize, so first conflicting slot will be reused. + break; + } + return false; + } +}; + +#endif // BUFFER_TICK_H diff --git a/Buffer/tests/BufferTick.test.mq4 b/Buffer/tests/BufferTick.test.mq4 new file mode 100644 index 000000000..5a45ef4fa --- /dev/null +++ b/Buffer/tests/BufferTick.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of BufferTick class. + */ + +// Includes. +#include "BufferTick.test.mq5" diff --git a/Buffer/tests/BufferTick.test.mq5 b/Buffer/tests/BufferTick.test.mq5 new file mode 100644 index 000000000..1daf2ea7b --- /dev/null +++ b/Buffer/tests/BufferTick.test.mq5 @@ -0,0 +1,57 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of BufferTick class. + */ + +// Includes +#include "../../Test.mqh" +#include "../BufferTick.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + MqlTick mql_tick; // 60 + TickAB _tick_ab_d; // 16 + TickAB _tick_ab_f; // 8 + TickTAB _tick_tab_d; // 24 + TickTAB _tick_tab_f; // 16 + Print("mql_tick: ", sizeof(mql_tick)); + Print("_tick_ab_d: ", sizeof(_tick_ab_d)); + Print("_tick_ab_f: ", sizeof(_tick_ab_f)); + Print("_tick_tab_d: ", sizeof(_tick_tab_d)); + Print("_tick_tab_f: ", sizeof(_tick_tab_f)); + // @todo + return (GetLastError() > 0 ? INIT_FAILED : INIT_SUCCEEDED); +} + +/** + * Implements OnTick(). + */ +void OnTick() {} + +/** + * Implements OnDeinit(). + */ +void OnDeinit(const int reason) {} diff --git a/Candle.struct.h b/Candle.struct.h index e713ceb22..2adbe4900 100644 --- a/Candle.struct.h +++ b/Candle.struct.h @@ -49,6 +49,7 @@ struct CandleOHLC #endif { T open, high, low, close; + // Struct constructors. CandleOHLC(T _open = 0, T _high = 0, T _low = 0, T _close = 0) : open(_open), high(_high), low(_low), close(_close) {} CandleOHLC(ARRAY_REF(T, _prices)) { int _size = ArraySize(_prices); diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index bf1487a03..9b1c3d6cf 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -30,15 +30,16 @@ #endif // Includes. +#include "../Buffer/BufferTick.h" #include "../IndicatorBase.h" /** * Class to deal with tick indicators. */ -template +template class IndicatorTick : public IndicatorBase { protected: - BufferStruct itdata; + BufferTick itdata; TS itparams; protected: @@ -85,6 +86,8 @@ class IndicatorTick : public IndicatorBase { */ IndicatorDataEntry GetEntry(int _timestamp = 0) { ResetLastError(); + TickAB _entry = itdata.GetByKey(_timestamp); + /* IndicatorDataEntry _entry = itdata.GetByKey(_timestamp); if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { _entry.Resize(itparams.GetMaxModes()); @@ -133,6 +136,9 @@ class IndicatorTick : public IndicatorBase { ResetLastError(); } return _entry; + */ + IndicatorDataEntry _foo; + return _foo; } /** @@ -165,17 +171,9 @@ class IndicatorTick : public IndicatorBase { * * @see: MqlTick. */ - void SetTick(MqlTick& _tick, long _timestamp = 0) { - IndicatorDataEntry _entry(itparams.GetMaxModes()); - _entry.timestamp = _timestamp; - _entry.values[0] = _tick.bid; - _entry.values[1] = _tick.ask; -#ifdef __MQL4__ - _entry.values[2] = _tick.volume; -#else - _entry.values[2] = _tick.volume_real; -#endif - itdata.Add(_entry, _timestamp); + void SetTick(MqlTick& _mql_tick, long _timestamp = 0) { + TickAB _tick(_mql_tick); + itdata.Add(_tick, _timestamp); } /** diff --git a/Indicator/tests/IndicatorTick.test.mq5 b/Indicator/tests/IndicatorTick.test.mq5 index 07bab9c74..0fc115be5 100644 --- a/Indicator/tests/IndicatorTick.test.mq5 +++ b/Indicator/tests/IndicatorTick.test.mq5 @@ -36,7 +36,7 @@ struct IndicatorTickDummyParams : IndicatorParams { /** * Price Indicator. */ -class IndicatorTickDummy : public IndicatorTick { +class IndicatorTickDummy : public IndicatorTick { public: IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 01d7dd2f7..db392ce69 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -44,7 +44,7 @@ struct IndiTickMtParams : IndicatorParams { /** * Price Indicator. */ -class Indi_TickMt : public IndicatorTick { +class Indi_TickMt : public IndicatorTick { protected: MqlTick tick; @@ -52,7 +52,8 @@ class Indi_TickMt : public IndicatorTick { /** * Class constructor. */ - Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTick(_p, _indi_src){}; + Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) + : IndicatorTick(_p, _indi_src){}; Indi_TickMt(string _symbol, int _shift = 0) : IndicatorTick(INDI_TICK, _symbol, _shift){}; /** @@ -86,7 +87,7 @@ class Indi_TickMt : public IndicatorTick { * This method is called on GetEntry() right after values are set. */ virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { - IndicatorTick::GetEntryAlter(_entry, _shift); + IndicatorTick::GetEntryAlter(_entry, _shift); _entry.timestamp = _entry.timestamp > 0 ? _entry.timestamp : tick.time; }; }; diff --git a/Tick.struct.h b/Tick.struct.h index 46d4efee4..0d36f8095 100644 --- a/Tick.struct.h +++ b/Tick.struct.h @@ -38,7 +38,7 @@ struct TickAB { T bid; // Current Bid price. // Struct constructors. TickAB(T _ask = 0, T _bid = 0) : ask(_ask), bid(_bid) {} - TickAB(MqlTick &_tick) : ask(_tick.ask), bid(_tick.bid) {} + TickAB(MqlTick &_tick) : ask((T)_tick.ask), bid((T)_tick.bid) {} }; /** @@ -49,7 +49,7 @@ struct TickTAB : TickAB { datetime time; // Time of the last prices update. // Struct constructors. TickTAB(datetime _time = 0, T _ask = 0, T _bid = 0) : time(_time), TickAB(_ask, _bid) {} - TickAB(MqlTick &_tick) : time(_tick.time), TickAB(_tick.ask, _tick.bid) {} + TickTAB(MqlTick &_tick) : time(_tick.time), TickAB(_tick) {} }; #ifndef __MQL__ From 11dd81219e7a3aee39ccea03e5c8fd2f756c3f4e Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 28 Oct 2021 21:58:12 +0100 Subject: [PATCH 22/81] Chart: ChartTf: Adds SecsToTf() --- Chart.struct.tf.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Chart.struct.tf.h b/Chart.struct.tf.h index 6c91b1c16..49c7c88f3 100644 --- a/Chart.struct.tf.h +++ b/Chart.struct.tf.h @@ -116,6 +116,69 @@ struct ChartTf { /* Static methods */ + /** + * Converts number of seconds per bar to chart's timeframe. + * + * @param _secs + * Number of seconds per one bar chart (OHLC). + * + * @return ENUM_TIMEFRAMES + * Returns enum representing chart's timeframe value. + */ + static ENUM_TIMEFRAMES SecsToTf(uint _secs = 0) { + switch (_secs) { + case 0: + return PERIOD_CURRENT; + case 60: + return PERIOD_M1; // 1 minute. + case 60 * 2: + return PERIOD_M2; // 2 minutes (non-standard). + case 60 * 3: + return PERIOD_M3; // 3 minutes (non-standard). + case 60 * 4: + return PERIOD_M4; // 4 minutes (non-standard). + case 60 * 5: + return PERIOD_M5; // 5 minutes. + case 60 * 6: + return PERIOD_M6; // 6 minutes (non-standard). + case 60 * 10: + return PERIOD_M10; // 10 minutes (non-standard). + case 60 * 12: + return PERIOD_M12; // 12 minutes (non-standard). + case 60 * 15: + return PERIOD_M15; // 15 minutes. + case 60 * 20: + return PERIOD_M20; // 20 minutes (non-standard). + case 60 * 30: + return PERIOD_M30; // 30 minutes. + case 60 * 60: + return PERIOD_H1; // 1 hour. + case 60 * 60 * 2: + return PERIOD_H2; // 2 hours (non-standard). + case 60 * 60 * 3: + return PERIOD_H3; // 3 hours (non-standard). + case 60 * 60 * 4: + return PERIOD_H4; // 4 hours. + case 60 * 60 * 6: + return PERIOD_H6; // 6 hours (non-standard). + case 60 * 60 * 8: + return PERIOD_H8; // 8 hours (non-standard). + case 60 * 60 * 12: + return PERIOD_H12; // 12 hours (non-standard). + case 60 * 60 * 24: + return PERIOD_D1; // Daily. + case 60 * 60 * 24 * 7: + return PERIOD_W1; // Weekly. + default: + break; + } + if (_secs >= 60 * 60 * 24 * 28 && _secs <= 60 * 60 * 24 * 31) { + return PERIOD_MN1; // Monthly range. + } + SetUserError(ERR_INVALID_PARAMETER); + return PERIOD_CURRENT; + } + /** * Convert period to proper chart timeframe value. * From 0b2e66f6522f5b07fc631996371616c367cb484b Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 11 Nov 2021 20:12:19 +0000 Subject: [PATCH 23/81] Indicator/IndicatorTf: Improves constructors --- Buffer/BufferTick.h | 16 ++++++++++++++++ Chart.struct.tf.h | 3 +-- Indicator/IndicatorTf.h | 23 +++++++++++++++++++---- Indicator/IndicatorTf.struct.h | 10 +++++++++- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/Buffer/BufferTick.h b/Buffer/BufferTick.h index 8e6ac9093..70965dcfe 100644 --- a/Buffer/BufferTick.h +++ b/Buffer/BufferTick.h @@ -56,6 +56,22 @@ class BufferTick : public BufferStruct> { Init(); } + /* Grouping methods */ + + /** + * Group ticks by seconds. + */ + DictStruct>> GroupBySecs(uint _spc) { + // DictStruct>> _result; + // @todo: for each iter + // for (DictStructIterator>> iter(Begin()); iter.IsValid(); ++iter) { + // Load timestamp from key, TickAB from value + // foreach some timestamp mod % _spc - calculate shift + // _result.Push(_shift, TickAB) + // Convert to OHLC in upper method + return NULL; + } + /* Callback methods */ /** diff --git a/Chart.struct.tf.h b/Chart.struct.tf.h index 49c7c88f3..7074f67e8 100644 --- a/Chart.struct.tf.h +++ b/Chart.struct.tf.h @@ -32,6 +32,7 @@ // Includes. #include "Chart.enum.h" +#include "Serializer.mqh" /* Defines struct for chart timeframe. */ struct ChartTf { @@ -346,8 +347,6 @@ 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/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index a64d22338..956fb2b45 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -30,6 +30,7 @@ #endif // Includes. +#include "../Chart.struct.tf.h" #include "IndicatorCandle.h" #include "IndicatorTf.struct.h" @@ -51,14 +52,28 @@ class IndicatorTf : public IndicatorCandle { /* Special methods */ /** - * Class constructor. + * Class constructor with timeframe enum. */ - IndicatorTf(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { Init(); } + IndicatorTf(uint _spc) { + icparams.SetSecsPerCandle(_spc); + Init(); + } /** - * Class constructor. + * Class constructor with timeframe enum. */ - IndicatorTf(ENUM_TIMEFRAMES_INDEX _tfi = 0) { Init(); } + IndicatorTf(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { + icparams.SetSecsPerCandle(ChartTf::TfToSeconds(_tf)); + Init(); + } + + /** + * Class constructor with timeframe index. + */ + IndicatorTf(ENUM_TIMEFRAMES_INDEX _tfi = 0) { + icparams.SetSecsPerCandle(ChartTf::TfToSeconds(ChartTf::IndexToTf(_tfi))); + Init(); + } /** * Class constructor with parameters. diff --git a/Indicator/IndicatorTf.struct.h b/Indicator/IndicatorTf.struct.h index 8e82a67bd..5feae87e4 100644 --- a/Indicator/IndicatorTf.struct.h +++ b/Indicator/IndicatorTf.struct.h @@ -30,10 +30,18 @@ #pragma once #endif +// Includes. +#include "../Indicator.struct.h" + /* Structure for IndicatorTf class parameters. */ struct IndicatorTfParams : IndicatorParams { + uint spc; // Seconds per candle. // Struct constructor. - IndicatorTfParams() {} + IndicatorTfParams(uint _spc = 60) : spc(_spc) {} + // Getters. + uint GetSecsPerCandle() { return spc; } + // Setters. + void SetSecsPerCandle(uint _spc) { spc = _spc; } // Copy constructor. IndicatorTfParams(const IndicatorTfParams &_params, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { THIS_REF = _params; From 112a998ab3b8fc4baa7fb1e0988c894118c05933 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 19 Nov 2021 22:02:24 +0100 Subject: [PATCH 24/81] Just some WIP. --- Candle.struct.h | 2 +- Indicator.enum.h | 1 + Indicator.mqh | 3 +-- Indicator/IndicatorCandle.h | 22 ++++++++++++++++++++-- Indicator/IndicatorTf.h | 5 +++-- Indicator/tests/IndicatorTf.test.mq5 | 21 +++++++++++++++++++++ 6 files changed, 47 insertions(+), 7 deletions(-) diff --git a/Candle.struct.h b/Candle.struct.h index 2adbe4900..6a7338c27 100644 --- a/Candle.struct.h +++ b/Candle.struct.h @@ -41,7 +41,7 @@ class Serializer; #include "SerializerNode.enum.h" #include "Std.h" -/* Structore for storing OHLC values. */ +/* Structure for storing OHLC values. */ template struct CandleOHLC #ifndef __MQL__ diff --git a/Indicator.enum.h b/Indicator.enum.h index 375064b34..63baad455 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -114,6 +114,7 @@ enum ENUM_INDICATOR_TYPE { INDI_STOCHASTIC, // Stochastic Oscillator INDI_SVE_BB, // SVE Bollinger Bands INDI_TEMA, // Triple Exponential Moving Average + INDI_TF, // Timeframe INDI_TICK, // Tick INDI_TMA_TRUE, // Triangular Moving Average True INDI_TRIX, // Triple Exponential Moving Averages Oscillator diff --git a/Indicator.mqh b/Indicator.mqh index da1721aa2..ccfe59441 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -1098,7 +1098,7 @@ class Indicator : public IndicatorBase { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - virtual IndicatorDataEntry GetEntry(int _index = -1) { + IndicatorDataEntry GetEntry(int _index = -1) override { ResetLastError(); int _ishift = _index >= 0 ? _index : iparams.GetShift(); long _bar_time = GetBarTime(_ishift); @@ -1293,7 +1293,6 @@ class Indicator : public IndicatorBase { COMMA _l COMMA _m); #endif } - }; #endif diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index ff2e0fdc2..7886ec953 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -61,7 +61,8 @@ class IndicatorCandle : public IndicatorBase { /** * Class constructor. */ - IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) : icparams(_icparams) { + IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { + icparams = _icparams; if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); } @@ -83,9 +84,26 @@ class IndicatorCandle : public IndicatorBase { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - IndicatorDataEntry GetEntry(int _timestamp = 0) { + IndicatorDataEntry GetEntry(int _index = -1) override { ResetLastError(); + int _ishift = _index >= 0 ? _index : icparams.GetShift(); + long _bar_time = GetBarTime(_ishift); + + // Trying to fetch entry from cache. + IndicatorDataEntry _entry = icdata.GetByKey(_bar_time); + + if (_bar_time > 0 && !_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { + // There is no valid entry in the cache. + _entry.Resize(iparams.GetMaxModes()); + _entry.timestamp = _bar_time; + } + CandleOHLC _entry = icdata.GetByKey(_timestamp); + + if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { + // There is no candle for given timestamp. + } + /* IndicatorDataEntry _entry = icdata.GetByKey(_timestamp); if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index 956fb2b45..21350c445 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -37,7 +37,8 @@ /** * Class to deal with candle indicators. */ -class IndicatorTf : public IndicatorCandle { +template +class IndicatorTf : public IndicatorCandle { protected: /* Protected methods */ @@ -78,7 +79,7 @@ class IndicatorTf : public IndicatorCandle { /** * Class constructor with parameters. */ - IndicatorTf(IndicatorTfParams &_params) : IndicatorCandle(_params) { Init(); } + IndicatorTf(TFP &_params) : IndicatorCandle(_params) { Init(); } }; #endif diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 5c68d79a2..ab020542a 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -22,16 +22,37 @@ /** * @file * Test functionality of IndicatorTf class. + * + * Idea is to check if ticks from IndicatorTick will be properly grouped by given timespan/timeframe. */ // Includes. #include "../../Test.mqh" #include "../IndicatorTf.h" +// Structs. +struct IndicatorTfDummyParams : IndicatorTfParams { + IndicatorTfDummyParams(uint _spc = 60) : IndicatorTfParams(_spc) {} +}; + +/** + * Price Indicator. + */ +class IndicatorTfDummy : public IndicatorTf { + public: + IndicatorTfDummy(uint _spc) : IndicatorTf(_spc) {} + IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {} + IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {} +}; + /** * Implements OnInit(). */ int OnInit() { // @todo + + // 1-second candles. + Ref indi_tf = new IndicatorTfDummy(1); + return (INIT_SUCCEEDED); } From 769631969ee8af9bdfbd915a68b45aa44b6bc3c9 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Mon, 22 Nov 2021 19:50:10 +0100 Subject: [PATCH 25/81] WIP. Added idea of event listeners for indicators and emitting a historic and new entries. --- Indicator.mqh | 5 ++ Indicator/IndicatorCandle.h | 104 ++++++++++--------------- Indicator/IndicatorTick.h | 18 +++++ Indicator/tests/IndicatorTf.test.mq5 | 33 ++++++++ Indicator/tests/IndicatorTick.test.mq5 | 23 +++++- IndicatorBase.h | 43 ++++++++++ Util.h | 14 ++++ 7 files changed, 175 insertions(+), 65 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index ccfe59441..389d9fc54 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -820,8 +820,13 @@ class Indicator : public IndicatorBase { * Sets indicator data source. */ void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { + if (indi_src.IsSet() && indi_src.Ptr() != _indi) { + indi_src.Ptr().RemoveListener(THIS_PTR); + } indi_src = _indi; + indi_src.Ptr().AddListener(THIS_PTR); iparams.SetDataSource(-1, _input_mode); + indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); } /** diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 7886ec953..f2321ff25 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -79,6 +79,17 @@ class IndicatorCandle : public IndicatorBase { /** * Returns the indicator's data entry. * + * We will fetch consecutive entries from the source indicator and check its + * timestamps. We need to gather entries matching calculated timespan. + * + * For example: We want 5s candle at shift=1. That mean we have to ask source + * indicator for entries between + * candle.timestamp + (1 * 5s) and candle.timestamp + (2 * 5s). + * + * The question is: How to calculate shift for source indicator's GetEntry()? + * + * + * * @see: IndicatorDataEntry. * * @return @@ -86,76 +97,18 @@ class IndicatorCandle : public IndicatorBase { */ IndicatorDataEntry GetEntry(int _index = -1) override { ResetLastError(); - int _ishift = _index >= 0 ? _index : icparams.GetShift(); + unsigned int _ishift = _index >= 0 ? _index : icparams.GetShift(); long _bar_time = GetBarTime(_ishift); - // Trying to fetch entry from cache. - IndicatorDataEntry _entry = icdata.GetByKey(_bar_time); + CandleOHLC _entry = icdata.GetByKey(_bar_time); - if (_bar_time > 0 && !_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - // There is no valid entry in the cache. - _entry.Resize(iparams.GetMaxModes()); - _entry.timestamp = _bar_time; + if (!_entry.IsValid()) { + // There is no candle and won't ever be for given timestamp. } - CandleOHLC _entry = icdata.GetByKey(_timestamp); - - if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - // There is no candle for given timestamp. - } + IndicatorDataEntry _data_entry; - /* - IndicatorDataEntry _entry = icdata.GetByKey(_timestamp); - if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - _entry.Resize(icparams.GetMaxModes()); - _entry.timestamp = _timestamp; - for (int _mode = 0; _mode < (int)icparams.GetMaxModes(); _mode++) { - switch (icparams.GetDataValueType()) { - case TYPE_BOOL: - case TYPE_CHAR: - case TYPE_INT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_LONG: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_UINT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_ULONG: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_DOUBLE: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_FLOAT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_STRING: - case TYPE_UCHAR: - default: - SetUserError(ERR_INVALID_PARAMETER); - break; - } - } - GetEntryAlter(_entry, _timestamp); - _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); - if (_entry.IsValid()) { - icdata.Add(_entry, _timestamp); - istate.is_changed = false; - istate.is_ready = true; - } else { - _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); - } - } - if (_LastError != ERR_NO_ERROR) { - istate.is_ready = false; - ResetLastError(); - } - return _entry; - */ - IndicatorDataEntry _foo; - return _foo; + return _data_entry; } /** @@ -197,12 +150,35 @@ class IndicatorCandle : public IndicatorBase { return false; } + /** + * Sends historic entries to listening indicators. May be overriden. + */ + void EmitHistory() override { + for (DictStructIterator> iter(icdata.Begin()); iter.IsValid(); ++iter) { + IndicatorDataEntry _entry = CandleToEntry(iter.Value()); + EmitEntry(_entry); + } + } + + /** + * @todo + */ + IndicatorDataEntry CandleToEntry(CandleOHLC& _candle) { + IndicatorDataEntry _entry; + return _entry; + } + /** * Sets indicator data source. */ void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { + if (indi_src.IsSet() && indi_src.Ptr() != _indi) { + indi_src.Ptr().RemoveListener(THIS_PTR); + } indi_src = _indi; + indi_src.Ptr().AddListener(THIS_PTR); icparams.SetDataSource(-1, _input_mode); + indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); } /* Virtual methods */ diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 9b1c3d6cf..e1213cc87 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -76,6 +76,24 @@ class IndicatorTick : public IndicatorBase { /* Virtual method implementations */ + /** + * Sends historic entries to listening indicators. May be overriden. + */ + void EmitHistory() override { + for (DictStructIterator> iter(itdata.Begin()); iter.IsValid(); ++iter) { + IndicatorDataEntry _entry = TickToEntry(iter.Value()); + EmitEntry(_entry); + } + } + + /** + * @todo + */ + IndicatorDataEntry TickToEntry(TickAB& _tick) { + IndicatorDataEntry _entry; + return _entry; + } + /** * Returns the indicator's data entry. * diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index ab020542a..75e5e19d9 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -29,6 +29,32 @@ // Includes. #include "../../Test.mqh" #include "../IndicatorTf.h" +#include "../IndicatorTick.h" + +// Structs. +struct IndicatorTickDummyParams : IndicatorParams { + IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} +}; + +class IndicatorTickDummy : public IndicatorTick { + public: + IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { + SetSymbol(_symbol); + } + + string GetName() override { return "IndicatorTickDummy"; } + + void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { + // Feeding base indicator with historic entries of this indicator. + Print(GetName(), " became a data source for ", _base_indi.GetName()); + + IndicatorDataEntry _entry; + EmitEntry(_entry); + EmitEntry(_entry); + EmitEntry(_entry); + }; +}; // Structs. struct IndicatorTfDummyParams : IndicatorTfParams { @@ -43,6 +69,10 @@ class IndicatorTfDummy : public IndicatorTf { IndicatorTfDummy(uint _spc) : IndicatorTf(_spc) {} IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {} IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {} + + string GetName() override { return "IndicatorTfDummy(" + IntegerToString(icparams.spc) + ")"; } + + void OnDataSourceEntry(IndicatorDataEntry& entry) override { Print(GetName(), " got new entry!"); }; }; /** @@ -51,8 +81,11 @@ class IndicatorTfDummy : public IndicatorTf { int OnInit() { // @todo + Ref indi_tick = new IndicatorTickDummy(_Symbol); + // 1-second candles. Ref indi_tf = new IndicatorTfDummy(1); + indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); return (INIT_SUCCEEDED); } diff --git a/Indicator/tests/IndicatorTick.test.mq5 b/Indicator/tests/IndicatorTick.test.mq5 index 0fc115be5..9b9a082e3 100644 --- a/Indicator/tests/IndicatorTick.test.mq5 +++ b/Indicator/tests/IndicatorTick.test.mq5 @@ -34,7 +34,28 @@ struct IndicatorTickDummyParams : IndicatorParams { }; /** - * Price Indicator. + * Tick indicator is an indicator that provides per-tick information. + * When asked to return data via GetEntry() it could fetch data from pre-made + * tick history or generate tick on-the-fly from remote source and save it in + * the history. + * + * Note that indicators could provide data also for future shifts, so shift=-10 + * is perfectly valid for them when doing GetEntry()/GetValue(). + * + * Tick indicator may become a data source for Candle indicator. In this + * scenario, when trying to fetch candle for a given shift, tick indicator is + * asked for ticks in a given timespan. E.g., Candle indicator may work in a 5s + * timespans, so when fetching candle with shift now+1, Tick indicator will be + * asked for ticks between now+5s and now+10s. + *rmf + * In order to fetch consecutive candles, you have to call + * IndicatorCandle::NextMaybe() to check whether new candle is ready to be + * processed. If yes, then new candle will be at index 0. + * + * if (indi_candle.NextMaybe()) { + * double _open = indi_candle.Open(0); // Shift 0 = current candle. + * double _close = indi_candle.Close(0); // Shift 0 = current candle. + * } */ class IndicatorTickDummy : public IndicatorTick { public: diff --git a/IndicatorBase.h b/IndicatorBase.h index e13b9ed17..d54f50417 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -70,6 +70,7 @@ class IndicatorBase : public Chart { Ref indi_src; // // Indicator used as data source. int indi_src_mode; // Mode of source indicator IndicatorCalculateCache cache; + ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. public: /* Indicator enumerations */ @@ -351,6 +352,22 @@ class IndicatorBase : public Chart { Chart::Set(_param, _value); } + /** + * Adds event listener. + */ + void AddListener(IndicatorBase* _indi) { + WeakRef _ref = _indi; + ArrayPushObject(listeners, _ref); + } + + /** + * Removes event listener. + */ + void RemoveListener(IndicatorBase* _indi) { + WeakRef _ref = _indi; + Util::ArrayRemoveFirst(listeners, _ref); + } + /** * Sets indicator data source. */ @@ -473,6 +490,32 @@ class IndicatorBase : public Chart { */ virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _index = -1) = NULL; + /** + * Sends entry to listening indicators. + */ + void EmitEntry(IndicatorDataEntry& entry) { + for (int i = 0; i < ArraySize(listeners); ++i) { + if (listeners[i].ObjectExists()) { + listeners[i].Ptr().OnDataSourceEntry(entry); + } + } + } + + /** + * Sends historic entries to listening indicators. May be overriden. + */ + virtual void EmitHistory() {} + + /** + * Called when data source emits new entry (historic or future one). + */ + virtual void OnDataSourceEntry(IndicatorDataEntry& entry){}; + + /** + * Called when indicator became a data source for other indicator. + */ + virtual void OnBecomeDataSourceFor(IndicatorBase* _base_indi){}; + /** * Returns indicator value for a given shift and mode. */ diff --git a/Util.h b/Util.h index 12ccb0c28..42a8a3009 100644 --- a/Util.h +++ b/Util.h @@ -65,6 +65,20 @@ class Util { return _result; } + /** + * Removes value from the array. + */ + template + static bool ArrayRemoveFirst(T& _array[], T& value) { + for (int i = 0; i < ArraySize(_array); ++i) { + if (_array[i] == value) { + ArrayRemove(_array, i); + return true; + } + } + return false; + } + template static T Print(T& _array[]) { string _result; From 1d2427aecd38ef111b0565c9144fcdff85e1a92c Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 23 Nov 2021 18:40:18 +0100 Subject: [PATCH 26/81] WIP. Added candle grouping when receiving ticks via OnDataSourceEntry(). --- Buffer/BufferCandle.h | 2 +- Candle.struct.h | 32 +++++++++++++++++ Indicator/IndicatorCandle.h | 52 +++++++++++++++++++++++++--- Indicator/IndicatorTick.h | 10 ++++-- Indicator/tests/IndicatorTf.test.mq5 | 36 +++++++++++++------ 5 files changed, 114 insertions(+), 18 deletions(-) diff --git a/Buffer/BufferCandle.h b/Buffer/BufferCandle.h index b0230c58a..8401ee3f8 100644 --- a/Buffer/BufferCandle.h +++ b/Buffer/BufferCandle.h @@ -32,7 +32,7 @@ * Class to store struct data. */ template -class BufferCandle : public BufferStruct> { +class BufferCandle : public BufferStruct> { protected: protected: /* Protected methods */ diff --git a/Candle.struct.h b/Candle.struct.h index 6a7338c27..4d4e03dfb 100644 --- a/Candle.struct.h +++ b/Candle.struct.h @@ -49,6 +49,7 @@ struct CandleOHLC #endif { T open, high, low, close; + // Struct constructors. CandleOHLC(T _open = 0, T _high = 0, T _low = 0, T _close = 0) : open(_open), high(_high), low(_low), close(_close) {} CandleOHLC(ARRAY_REF(T, _prices)) { @@ -216,6 +217,37 @@ struct CandleOHLC string ToCSV() { return StringFormat("%g,%g,%g,%g", open, high, low, close); } }; +/* Structure for storing OHLC values with open and close timestamp. */ +template +struct CandleOCTOHLC : CandleOHLC { + long open_timestamp, close_timestamp; + + // Struct constructors. + CandleOCTOHLC(T _open = 0, T _high = 0, T _low = 0, T _close = 0, long _open_timestamp = -1, + long _close_timestamp = -1) + : CandleOHLC(_open, _high, _low, _close), open_timestamp(_open_timestamp), close_timestamp(_close_timestamp) {} + + // Updates OHLC values taking into consideration tick's timestamp. + void Update(long _timestamp, T _price) { + if (_timestamp < open_timestamp) { + open_timestamp = _timestamp; + open = _price; + } + if (_timestamp > close_timestamp) { + close_timestamp = _timestamp; + close = _price; + } + high = MathMax(high, _price); + low = MathMin(low, _price); + } + + // Returns timestamp of open price. + long GetOpenTimestamp() { return open_timestamp; } + + // Returns timestamp of close price. + long GetCloseTimestamp() { return close_timestamp; } +}; + /* Structore for storing OHLC values with timestamp. */ template struct CandleTOHLC : CandleOHLC { diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index f2321ff25..603a20117 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -154,8 +154,8 @@ class IndicatorCandle : public IndicatorBase { * Sends historic entries to listening indicators. May be overriden. */ void EmitHistory() override { - for (DictStructIterator> iter(icdata.Begin()); iter.IsValid(); ++iter) { - IndicatorDataEntry _entry = CandleToEntry(iter.Value()); + for (DictStructIterator> iter(icdata.Begin()); iter.IsValid(); ++iter) { + IndicatorDataEntry _entry = CandleToEntry(iter.Key(), iter.Value()); EmitEntry(_entry); } } @@ -163,11 +163,46 @@ class IndicatorCandle : public IndicatorBase { /** * @todo */ - IndicatorDataEntry CandleToEntry(CandleOHLC& _candle) { - IndicatorDataEntry _entry; + IndicatorDataEntry CandleToEntry(long _timestamp, CandleOCTOHLC& _candle) { + IndicatorDataEntry _entry(4); + _entry.timestamp = _timestamp; + _entry.values[0] = _candle.open; + _entry.values[1] = _candle.high; + _entry.values[2] = _candle.low; + _entry.values[3] = _candle.close; + _entry.SetFlags(INDI_ENTRY_FLAG_IS_VALID); return _entry; } + /** + * Adds tick's price to the matching candle and updates its OHLC values. + */ + void UpdateCandle(long _tick_timestamp, double _price) { + long _candle_timestamp = CalcCandleTimestamp(_tick_timestamp); + + CandleOCTOHLC _candle; + if (icdata.KeyExists(_candle_timestamp)) { + _candle = icdata.GetByKey(_candle_timestamp); + _candle.Update(_tick_timestamp, _price); + } else { + _candle = CandleOCTOHLC(_price, _price, _price, _price, _tick_timestamp, _tick_timestamp); + } + + icdata.Set(_candle_timestamp, _candle); + } + + /** + * Calculates candle's timestamp from tick's timestamp. + */ + long CalcCandleTimestamp(long _tick_timestamp) { + return _tick_timestamp - _tick_timestamp % (icparams.GetSecsPerCandle() * 1000); + } + + /** + * Called when data source emits new entry (historic or future one). + */ + virtual void OnDataSourceEntry(IndicatorDataEntry& entry) { UpdateCandle(entry.timestamp, entry[0]); }; + /** * Sets indicator data source. */ @@ -181,6 +216,15 @@ class IndicatorCandle : public IndicatorBase { indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); } + string CandlesToString() { + string _result; + for (DictStructIterator> iter(icdata.Begin()); iter.IsValid(); ++iter) { + IndicatorDataEntry _entry = CandleToEntry(iter.Key(), iter.Value()); + _result += IntegerToString(iter.Key()) + ": " + _entry.ToString() + "\n"; + } + return _result; + } + /* Virtual methods */ /** diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index e1213cc87..5d7dd0925 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -81,7 +81,7 @@ class IndicatorTick : public IndicatorBase { */ void EmitHistory() override { for (DictStructIterator> iter(itdata.Begin()); iter.IsValid(); ++iter) { - IndicatorDataEntry _entry = TickToEntry(iter.Value()); + IndicatorDataEntry _entry = TickToEntry(iter.Key(), iter.Value()); EmitEntry(_entry); } } @@ -89,8 +89,12 @@ class IndicatorTick : public IndicatorBase { /** * @todo */ - IndicatorDataEntry TickToEntry(TickAB& _tick) { - IndicatorDataEntry _entry; + IndicatorDataEntry TickToEntry(long _timestamp, TickAB& _tick) { + IndicatorDataEntry _entry(2); + _entry.timestamp = _timestamp; + _entry.values[0] = _tick.ask; + _entry.values[1] = _tick.bid; + _entry.SetFlags(INDI_ENTRY_FLAG_IS_VALID); return _entry; } diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 75e5e19d9..a16b19aec 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -31,11 +31,12 @@ #include "../IndicatorTf.h" #include "../IndicatorTick.h" -// Structs. +// Parasms for dummy tick-based indicator. struct IndicatorTickDummyParams : IndicatorParams { IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} }; +// Dummy tick-based indicator. class IndicatorTickDummy : public IndicatorTick { public: IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") @@ -49,20 +50,24 @@ class IndicatorTickDummy : public IndicatorTick(1.0f, 1.01f))); + EmitEntry(TickToEntry(1500, TickAB(1.5f, 1.51f))); + EmitEntry(TickToEntry(2000, TickAB(2.0f, 2.01f))); + EmitEntry(TickToEntry(3000, TickAB(3.0f, 3.01f))); + EmitEntry(TickToEntry(4000, TickAB(4.0f, 4.01f))); + EmitEntry(TickToEntry(4100, TickAB(4.1f, 4.11f))); + EmitEntry(TickToEntry(4200, TickAB(4.2f, 4.21f))); + EmitEntry(TickToEntry(4800, TickAB(4.8f, 4.81f))); }; }; -// Structs. +// Params for dummy candle-based indicator. struct IndicatorTfDummyParams : IndicatorTfParams { IndicatorTfDummyParams(uint _spc = 60) : IndicatorTfParams(_spc) {} }; /** - * Price Indicator. + * Dummy candle-based indicator. */ class IndicatorTfDummy : public IndicatorTf { public: @@ -72,20 +77,31 @@ class IndicatorTfDummy : public IndicatorTf { string GetName() override { return "IndicatorTfDummy(" + IntegerToString(icparams.spc) + ")"; } - void OnDataSourceEntry(IndicatorDataEntry& entry) override { Print(GetName(), " got new entry!"); }; + void OnDataSourceEntry(IndicatorDataEntry& entry) override { + // When overriding OnDataSourceEntry() we have to remember to call parent + // method, because IndicatorCandle also need to invoke it in order to + // create/update matching candle. + IndicatorTf::OnDataSourceEntry(entry); + + Print(GetName(), " got new tick at ", entry.timestamp, ": ", entry.ToString()); + } }; /** * Implements OnInit(). */ int OnInit() { - // @todo - Ref indi_tick = new IndicatorTickDummy(_Symbol); // 1-second candles. Ref indi_tf = new IndicatorTfDummy(1); + + // Candles will take data from tick indicator. indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); + // Printing all grouped candles. + Print(indi_tf.Ptr().GetName(), "'s candles:"); + Print(indi_tf.Ptr().CandlesToString()); + return (INIT_SUCCEEDED); } From e625d6ffc3fc522c84551294d744dab9f09293b8 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 25 Nov 2021 18:57:22 +0100 Subject: [PATCH 27/81] Working simulation of real ticking indicator. --- Indicator/IndicatorCandle.h | 5 +- Indicator/tests/IndicatorTf.test.mq5 | 95 +++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 603a20117..fa740f392 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -201,7 +201,10 @@ class IndicatorCandle : public IndicatorBase { /** * Called when data source emits new entry (historic or future one). */ - virtual void OnDataSourceEntry(IndicatorDataEntry& entry) { UpdateCandle(entry.timestamp, entry[0]); }; + virtual void OnDataSourceEntry(IndicatorDataEntry& entry) { + // Updating candle from bid price. + UpdateCandle(entry.timestamp, entry[1]); + }; /** * Sets indicator data source. diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index a16b19aec..3593d6194 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -28,12 +28,50 @@ // Includes. #include "../../Test.mqh" +#include "../../Util.h" #include "../IndicatorTf.h" #include "../IndicatorTick.h" -// Parasms for dummy tick-based indicator. +// Params for real tick-based indicator. +struct IndicatorTickRealParams : IndicatorParams { + IndicatorTickRealParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} +}; + +// Real tick-based indicator. +class IndicatorTickReal : public IndicatorTick { + public: + IndicatorTickReal(string _symbol, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { + SetSymbol(_symbol); + } + + string GetName() override { return "IndicatorTickDummy"; } + + void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { + // Feeding base indicator with historic entries of this indicator. + Print(GetName(), " became a data source for ", _base_indi.GetName()); + + int _ticks_to_emit = 100; + + // For testing purposes we are emitting 100 last ticks. + for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { + long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); + double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); + EmitEntry(TickToEntry(_timestamp, TickAB(0.0f, _bid))); + } + }; + + void OnTick() override { + long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf()); + double _bid = ChartStatic::iClose(GetSymbol(), GetTf()); + // MT doesn't provide historical ask prices, so we're filling tick with bid price only. + EmitEntry(TickToEntry(_timestamp, TickAB(_bid, _bid))); + } +}; + +// Params for dummy tick-based indicator. struct IndicatorTickDummyParams : IndicatorParams { - IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} + IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 2, TYPE_DOUBLE) {} }; // Dummy tick-based indicator. @@ -87,21 +125,62 @@ class IndicatorTfDummy : public IndicatorTf { } }; +/** + * Helper class to store all indicators and call OnTick() on them. + */ +class _Indicators { + Ref _indis[]; + + public: + void Add(IndicatorBase* _indi) { + Ref _ref = _indi; + ArrayPushObject(_indis, _ref); + } + + void Remove(IndicatorBase* _indi) { + Ref _ref = _indi; + Util::ArrayRemoveFirst(_indis, _ref); + } + + void Tick() { + for (int i = 0; i < ArraySize(_indis); ++i) { + _indis[i].Ptr().OnTick(); + } + } + +} indicators; + +Ref indi_tick; +Ref indi_tf; + /** * Implements OnInit(). */ int OnInit() { - Ref indi_tick = new IndicatorTickDummy(_Symbol); + indicators.Add(indi_tick = new IndicatorTickReal(_Symbol)); // 1-second candles. - Ref indi_tf = new IndicatorTfDummy(1); + indicators.Add(indi_tf = new IndicatorTfDummy(1)); - // Candles will take data from tick indicator. + // Candles will be initialized from tick's history. indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); - // Printing all grouped candles. - Print(indi_tf.Ptr().GetName(), "'s candles:"); + // Checking if there are candles for last 100 ticks. + Print(indi_tf.Ptr().GetName(), "'s historic candles (from 100 ticks):"); Print(indi_tf.Ptr().CandlesToString()); - return (INIT_SUCCEEDED); } + +/** + * Implements OnTick(). + */ +void OnTick() { indicators.Tick(); } + +/** + * Implements OnDeinit(). + */ +void OnDeinit(const int reason) { + // Printing all grouped candles. + Print(indi_tf.Ptr().GetName(), "'s all candles:"); + Print(indi_tf.Ptr().CandlesToString()); +} From 04378bd12ecbc66eed7325aee36a6fccafda850e Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 26 Nov 2021 20:00:02 +0100 Subject: [PATCH 28/81] Moved example indicator classes into separate files. Added OnIndicator support for AMA indicator. --- Indicator/IndicatorCandle.h | 28 +--- Indicator/tests/IndicatorTf.test.mq5 | 135 +++---------------- Indicator/tests/classes/IndicatorTfDummy.h | 56 ++++++++ Indicator/tests/classes/IndicatorTickDummy.h | 29 ++++ Indicator/tests/classes/IndicatorTickReal.h | 67 +++++++++ Indicator/tests/classes/Indicators.h | 73 ++++++++++ IndicatorBase.h | 4 + Indicators/Indi_AMA.mqh | 18 ++- Storage/ValueStorage.h | 4 + 9 files changed, 272 insertions(+), 142 deletions(-) create mode 100644 Indicator/tests/classes/IndicatorTfDummy.h create mode 100644 Indicator/tests/classes/IndicatorTickDummy.h create mode 100644 Indicator/tests/classes/IndicatorTickReal.h create mode 100644 Indicator/tests/classes/Indicators.h diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index fa740f392..31fa5bee4 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -79,17 +79,6 @@ class IndicatorCandle : public IndicatorBase { /** * Returns the indicator's data entry. * - * We will fetch consecutive entries from the source indicator and check its - * timestamps. We need to gather entries matching calculated timespan. - * - * For example: We want 5s candle at shift=1. That mean we have to ask source - * indicator for entries between - * candle.timestamp + (1 * 5s) and candle.timestamp + (2 * 5s). - * - * The question is: How to calculate shift for source indicator's GetEntry()? - * - * - * * @see: IndicatorDataEntry. * * @return @@ -98,17 +87,14 @@ class IndicatorCandle : public IndicatorBase { IndicatorDataEntry GetEntry(int _index = -1) override { ResetLastError(); unsigned int _ishift = _index >= 0 ? _index : icparams.GetShift(); - long _bar_time = GetBarTime(_ishift); - - CandleOHLC _entry = icdata.GetByKey(_bar_time); + long _candle_time = CalcCandleTimestamp(GetBarTime(_ishift)); + CandleOCTOHLC _candle = icdata.GetByKey(_candle_time); - if (!_entry.IsValid()) { - // There is no candle and won't ever be for given timestamp. + if (!_candle.IsValid()) { + Print(GetName(), ": Missing candle at shift ", _index, " (", _candle_time, ")"); } - IndicatorDataEntry _data_entry; - - return _data_entry; + return CandleToEntry(_candle_time, _candle); } /** @@ -161,7 +147,7 @@ class IndicatorCandle : public IndicatorBase { } /** - * @todo + * Converts candle into indicator's data entry. */ IndicatorDataEntry CandleToEntry(long _timestamp, CandleOCTOHLC& _candle) { IndicatorDataEntry _entry(4); @@ -170,7 +156,7 @@ class IndicatorCandle : public IndicatorBase { _entry.values[1] = _candle.high; _entry.values[2] = _candle.low; _entry.values[3] = _candle.close; - _entry.SetFlags(INDI_ENTRY_FLAG_IS_VALID); + _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, _candle.IsValid()); return _entry; } diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 3593d6194..0096c7310 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -27,131 +27,19 @@ */ // Includes. +#include "../../Indicators/Indi_AMA.mqh" #include "../../Test.mqh" #include "../../Util.h" #include "../IndicatorTf.h" #include "../IndicatorTick.h" +#include "classes/IndicatorTfDummy.h" +#include "classes/IndicatorTickReal.h" +#include "classes/Indicators.h" -// Params for real tick-based indicator. -struct IndicatorTickRealParams : IndicatorParams { - IndicatorTickRealParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} -}; - -// Real tick-based indicator. -class IndicatorTickReal : public IndicatorTick { - public: - IndicatorTickReal(string _symbol, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { - SetSymbol(_symbol); - } - - string GetName() override { return "IndicatorTickDummy"; } - - void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { - // Feeding base indicator with historic entries of this indicator. - Print(GetName(), " became a data source for ", _base_indi.GetName()); - - int _ticks_to_emit = 100; - - // For testing purposes we are emitting 100 last ticks. - for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { - long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); - double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); - EmitEntry(TickToEntry(_timestamp, TickAB(0.0f, _bid))); - } - }; - - void OnTick() override { - long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf()); - double _bid = ChartStatic::iClose(GetSymbol(), GetTf()); - // MT doesn't provide historical ask prices, so we're filling tick with bid price only. - EmitEntry(TickToEntry(_timestamp, TickAB(_bid, _bid))); - } -}; - -// Params for dummy tick-based indicator. -struct IndicatorTickDummyParams : IndicatorParams { - IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 2, TYPE_DOUBLE) {} -}; - -// Dummy tick-based indicator. -class IndicatorTickDummy : public IndicatorTick { - public: - IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { - SetSymbol(_symbol); - } - - string GetName() override { return "IndicatorTickDummy"; } - - void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { - // Feeding base indicator with historic entries of this indicator. - Print(GetName(), " became a data source for ", _base_indi.GetName()); - - EmitEntry(TickToEntry(1000, TickAB(1.0f, 1.01f))); - EmitEntry(TickToEntry(1500, TickAB(1.5f, 1.51f))); - EmitEntry(TickToEntry(2000, TickAB(2.0f, 2.01f))); - EmitEntry(TickToEntry(3000, TickAB(3.0f, 3.01f))); - EmitEntry(TickToEntry(4000, TickAB(4.0f, 4.01f))); - EmitEntry(TickToEntry(4100, TickAB(4.1f, 4.11f))); - EmitEntry(TickToEntry(4200, TickAB(4.2f, 4.21f))); - EmitEntry(TickToEntry(4800, TickAB(4.8f, 4.81f))); - }; -}; - -// Params for dummy candle-based indicator. -struct IndicatorTfDummyParams : IndicatorTfParams { - IndicatorTfDummyParams(uint _spc = 60) : IndicatorTfParams(_spc) {} -}; - -/** - * Dummy candle-based indicator. - */ -class IndicatorTfDummy : public IndicatorTf { - public: - IndicatorTfDummy(uint _spc) : IndicatorTf(_spc) {} - IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {} - IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {} - - string GetName() override { return "IndicatorTfDummy(" + IntegerToString(icparams.spc) + ")"; } - - void OnDataSourceEntry(IndicatorDataEntry& entry) override { - // When overriding OnDataSourceEntry() we have to remember to call parent - // method, because IndicatorCandle also need to invoke it in order to - // create/update matching candle. - IndicatorTf::OnDataSourceEntry(entry); - - Print(GetName(), " got new tick at ", entry.timestamp, ": ", entry.ToString()); - } -}; - -/** - * Helper class to store all indicators and call OnTick() on them. - */ -class _Indicators { - Ref _indis[]; - - public: - void Add(IndicatorBase* _indi) { - Ref _ref = _indi; - ArrayPushObject(_indis, _ref); - } - - void Remove(IndicatorBase* _indi) { - Ref _ref = _indi; - Util::ArrayRemoveFirst(_indis, _ref); - } - - void Tick() { - for (int i = 0; i < ArraySize(_indis); ++i) { - _indis[i].Ptr().OnTick(); - } - } - -} indicators; - +Indicators indicators; Ref indi_tick; Ref indi_tf; +Ref indi_ama; /** * Implements OnInit(). @@ -162,9 +50,15 @@ int OnInit() { // 1-second candles. indicators.Add(indi_tf = new IndicatorTfDummy(1)); + // 1-second candles. + indicators.Add(indi_ama = new Indi_AMA()); + // Candles will be initialized from tick's history. indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); + // AMA will work on the candle indicator. + indi_ama.Ptr().SetDataSource(indi_tf.Ptr()); + // Checking if there are candles for last 100 ticks. Print(indi_tf.Ptr().GetName(), "'s historic candles (from 100 ticks):"); Print(indi_tf.Ptr().CandlesToString()); @@ -174,7 +68,10 @@ int OnInit() { /** * Implements OnTick(). */ -void OnTick() { indicators.Tick(); } +void OnTick() { + indicators.Tick(); + Print("Tick: \n" + indicators.ToString(0)); +} /** * Implements OnDeinit(). diff --git a/Indicator/tests/classes/IndicatorTfDummy.h b/Indicator/tests/classes/IndicatorTfDummy.h new file mode 100644 index 000000000..fc79a3634 --- /dev/null +++ b/Indicator/tests/classes/IndicatorTfDummy.h @@ -0,0 +1,56 @@ +//+------------------------------------------------------------------+ +//| 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 + * Dummy candle-based indicator. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Params for dummy candle-based indicator. +struct IndicatorTfDummyParams : IndicatorTfParams { + IndicatorTfDummyParams(uint _spc = 60) : IndicatorTfParams(_spc) {} +}; + +/** + * Dummy candle-based indicator. + */ +class IndicatorTfDummy : public IndicatorTf { + public: + IndicatorTfDummy(uint _spc) : IndicatorTf(_spc) {} + IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {} + IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {} + + string GetName() override { return "IndicatorTfDummy(" + IntegerToString(icparams.spc) + ")"; } + + void OnDataSourceEntry(IndicatorDataEntry& entry) override { + // When overriding OnDataSourceEntry() we have to remember to call parent + // method, because IndicatorCandle also need to invoke it in order to + // create/update matching candle. + IndicatorTf::OnDataSourceEntry(entry); + + Print(GetName(), " got new tick at ", entry.timestamp, ": ", entry.ToString()); + } +}; diff --git a/Indicator/tests/classes/IndicatorTickDummy.h b/Indicator/tests/classes/IndicatorTickDummy.h new file mode 100644 index 000000000..355659ff9 --- /dev/null +++ b/Indicator/tests/classes/IndicatorTickDummy.h @@ -0,0 +1,29 @@ +// Params for dummy tick-based indicator. +struct IndicatorTickDummyParams : IndicatorParams { + IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 2, TYPE_DOUBLE) {} +}; + +// Dummy tick-based indicator. +class IndicatorTickDummy : public IndicatorTick { + public: + IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { + SetSymbol(_symbol); + } + + string GetName() override { return "IndicatorTickDummy"; } + + void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { + // Feeding base indicator with historic entries of this indicator. + Print(GetName(), " became a data source for ", _base_indi.GetName()); + + EmitEntry(TickToEntry(1000, TickAB(1.0f, 1.01f))); + EmitEntry(TickToEntry(1500, TickAB(1.5f, 1.51f))); + EmitEntry(TickToEntry(2000, TickAB(2.0f, 2.01f))); + EmitEntry(TickToEntry(3000, TickAB(3.0f, 3.01f))); + EmitEntry(TickToEntry(4000, TickAB(4.0f, 4.01f))); + EmitEntry(TickToEntry(4100, TickAB(4.1f, 4.11f))); + EmitEntry(TickToEntry(4200, TickAB(4.2f, 4.21f))); + EmitEntry(TickToEntry(4800, TickAB(4.8f, 4.81f))); + }; +}; diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h new file mode 100644 index 000000000..00a2aafb3 --- /dev/null +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -0,0 +1,67 @@ +//+------------------------------------------------------------------+ +//| 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 + * Real tick-based indicator. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Params for real tick-based indicator. +struct IndicatorTickRealParams : IndicatorParams { + IndicatorTickRealParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} +}; + +// Real tick-based indicator. +class IndicatorTickReal : public IndicatorTick { + public: + IndicatorTickReal(string _symbol, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { + SetSymbol(_symbol); + } + + string GetName() override { return "IndicatorTickDummy"; } + + void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { + // Feeding base indicator with historic entries of this indicator. + Print(GetName(), " became a data source for ", _base_indi.GetName()); + + int _ticks_to_emit = 100; + + // For testing purposes we are emitting 100 last ticks. + for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { + long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); + double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); + EmitEntry(TickToEntry(_timestamp, TickAB(0.0f, _bid))); + } + }; + + void OnTick() override { + long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf()); + double _bid = ChartStatic::iClose(GetSymbol(), GetTf()); + // MT doesn't provide historical ask prices, so we're filling tick with bid price only. + EmitEntry(TickToEntry(_timestamp, TickAB(_bid, _bid))); + } +}; diff --git a/Indicator/tests/classes/Indicators.h b/Indicator/tests/classes/Indicators.h new file mode 100644 index 000000000..2022df473 --- /dev/null +++ b/Indicator/tests/classes/Indicators.h @@ -0,0 +1,73 @@ +//+------------------------------------------------------------------+ +//| 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 + * Helper class to store all indicators and call OnTick() on them. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../../../IndicatorBase.h" +#include "../../../Refs.mqh" + +/** + * Helper class to store all indicators and call OnTick() on them. + */ +class Indicators { + Ref _indis[]; + + public: + void Add(IndicatorBase* _indi) { + Ref _ref = _indi; + ArrayPushObject(_indis, _ref); + } + + void Remove(IndicatorBase* _indi) { + Ref _ref = _indi; + Util::ArrayRemoveFirst(_indis, _ref); + } + + /** + * Executes OnTick() on every added indicator. + */ + void Tick() { + for (int i = 0; i < ArraySize(_indis); ++i) { + _indis[i].Ptr().OnTick(); + } + } + + /** + * Prints indicators' values at the given shift. + */ + string ToString(int _shift = 0) { + string _result; + for (int i = 0; i < ArraySize(_indis); ++i) { + IndicatorDataEntry _entry = _indis[i].Ptr().GetEntry(_shift); + _result += _indis[i].Ptr().GetName() + " = " + _entry.ToString() + "\n"; + } + return _result; + } +}; diff --git a/IndicatorBase.h b/IndicatorBase.h index d54f50417..d1f61d607 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -413,6 +413,10 @@ class IndicatorBase : public Chart { } ValueStorage* GetValueStorage(int _mode = 0) { + if (_mode >= ArraySize(value_storages)) { + ArrayResize(value_storages, _mode + 1); + } + if (value_storages[_mode] == NULL) { value_storages[_mode] = new IndicatorBufferValueStorage(THIS_PTR, _mode); } diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 58a8bee10..25028689a 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -88,6 +88,19 @@ class Indi_AMA : public Indicator { #endif } + /** + * On-indicator version of AMA. + */ + static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, + int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, + Util::MakeKey("INDI_AMA", _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, (int)_ap)); + return iAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ama_period, _fast_ema_period, _slow_ema_period, + _ama_shift, _mode, _shift, _cache); + } + /** * Calculates AMA on the array of values. */ @@ -213,8 +226,9 @@ class Indi_AMA : public Indicator { break; case IDATA_INDICATOR: - // @todo - SetUserError(ERR_INVALID_PARAMETER); + _value = Indi_AMA::iAMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFastPeriod(), + GetSlowPeriod(), GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, + THIS_PTR); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Storage/ValueStorage.h b/Storage/ValueStorage.h index cf9105c30..6fa64909a 100644 --- a/Storage/ValueStorage.h +++ b/Storage/ValueStorage.h @@ -87,6 +87,10 @@ enum ENUM_IPEAK { IPEAK_LOWEST, IPEAK_HIGHEST }; ValueStorage *_price = PriceValueStorage::GetInstance(SYMBOL, TF, APPLIED_PRICE); \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) +#define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS(INDI, SYMBOL, TF, APPLIED_PRICE, KEY) \ + ValueStorage *_price = INDI.GetValueStorage(APPLIED_PRICE); \ + INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) + #define INDICATOR_CALCULATE_POPULATED_PARAMS_LONG \ _time, _price_open, _price_high, _price_low, _price_close, _tick_volume, _volume, _spread From f7b99ec15b59ee1903b25753e7d9006e8f017817 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 26 Nov 2021 22:04:51 +0100 Subject: [PATCH 29/81] Added support for MT4. --- Indicator/IndicatorCandle.h | 5 ++--- Indicator/tests/classes/IndicatorTickReal.h | 6 ++++-- Util.h | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 31fa5bee4..2bf8a760c 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -166,12 +166,11 @@ class IndicatorCandle : public IndicatorBase { void UpdateCandle(long _tick_timestamp, double _price) { long _candle_timestamp = CalcCandleTimestamp(_tick_timestamp); - CandleOCTOHLC _candle; + CandleOCTOHLC _candle(_price, _price, _price, _price, _tick_timestamp, _tick_timestamp); if (icdata.KeyExists(_candle_timestamp)) { + // Candle already exists. _candle = icdata.GetByKey(_candle_timestamp); _candle.Update(_tick_timestamp, _price); - } else { - _candle = CandleOCTOHLC(_price, _price, _price, _price, _tick_timestamp, _tick_timestamp); } icdata.Set(_candle_timestamp, _candle); diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index 00a2aafb3..c3c36269d 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -54,7 +54,8 @@ class IndicatorTickReal : public IndicatorTick for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); - EmitEntry(TickToEntry(_timestamp, TickAB(0.0f, _bid))); + TickAB _tick(0.0f, _bid); + EmitEntry(TickToEntry(_timestamp, _tick)); } }; @@ -62,6 +63,7 @@ class IndicatorTickReal : public IndicatorTick long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf()); double _bid = ChartStatic::iClose(GetSymbol(), GetTf()); // MT doesn't provide historical ask prices, so we're filling tick with bid price only. - EmitEntry(TickToEntry(_timestamp, TickAB(_bid, _bid))); + TickAB _tick(_bid, _bid); + EmitEntry(TickToEntry(_timestamp, _tick)); } }; diff --git a/Util.h b/Util.h index 42a8a3009..739fb9f85 100644 --- a/Util.h +++ b/Util.h @@ -65,6 +65,22 @@ class Util { return _result; } + /** + * Removes value from the array. + */ + template + static bool ArrayRemove(T& _array[], int index) { + if (index < 0 || index >= ArraySize(_array)) { + // Index out of array bounds. + return false; + } + for (int i = index; i < ArraySize(_array); ++i) { + _array[i] = _array[i + 1]; + } + Util::ArrayResize(_array, ArraySize(_array) - 1); + return true; + } + /** * Removes value from the array. */ @@ -72,7 +88,7 @@ class Util { static bool ArrayRemoveFirst(T& _array[], T& value) { for (int i = 0; i < ArraySize(_array); ++i) { if (_array[i] == value) { - ArrayRemove(_array, i); + Util::ArrayRemove(_array, i); return true; } } From 3537a04ae292a953036f5df1d2c5f52ce7ebfe38 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 30 Nov 2021 18:12:37 +0100 Subject: [PATCH 30/81] WIP. Trying to make "AMA on Candle indicator on Tick indicator" to print the same results as original AMA based on real platform ticks. Currently without a success. --- Indicator/IndicatorCandle.h | 45 +++++++++++++++++++++ Indicator/tests/IndicatorTf.test.mq5 | 23 ++++++++++- Indicator/tests/classes/IndicatorTfDummy.h | 3 +- Indicator/tests/classes/IndicatorTickReal.h | 9 +++-- Indicator/tests/classes/Indicators.h | 2 +- Util.h | 15 +++++++ 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 2bf8a760c..e229d0539 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -254,6 +254,51 @@ class IndicatorCandle : public IndicatorBase { } return _result; } + + /** + * Get full name of the indicator (with "over ..." part). + */ + string GetFullName() override { + return GetName() + "[" + IntegerToString(icparams.GetMaxModes()) + "]" + + (HasDataSource() ? (" (over " + GetDataSource().GetFullName() + ")") : ""); + } + + /** + * Whether data source is selected. + */ + bool HasDataSource() override { return GetDataSourceRaw() != NULL || icparams.GetDataSourceId() != -1; } + + /** + * Returns currently selected data source doing validation. + */ + IndicatorBase* GetDataSource() override { + IndicatorBase* _result = NULL; + + if (GetDataSourceRaw() != NULL) { + _result = GetDataSourceRaw(); + } else if (icparams.GetDataSourceId() != -1) { + int _source_id = icparams.GetDataSourceId(); + + if (indicators.KeyExists(_source_id)) { + _result = indicators[_source_id].Ptr(); + } else { + Ref _source = FetchDataSource((ENUM_INDICATOR_TYPE)_source_id); + + if (!_source.IsSet()) { + Alert(GetName(), " has no built-in source indicator ", _source_id); + DebugBreak(); + } else { + indicators.Set(_source_id, _source); + + _result = _source.Ptr(); + } + } + } + + ValidateDataSource(&this, _result); + + return _result; + } }; #endif diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 0096c7310..7f9aa4d4d 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -39,7 +39,10 @@ Indicators indicators; Ref indi_tick; Ref indi_tf; +Ref indi_tf_orig_sim; Ref indi_ama; +Ref indi_ama_orig; +Ref indi_ama_orig_sim; /** * Implements OnInit(). @@ -50,15 +53,28 @@ int OnInit() { // 1-second candles. indicators.Add(indi_tf = new IndicatorTfDummy(1)); + // 1:1 candles from platform using current timeframe. + indicators.Add(indi_tf_orig_sim = new IndicatorTfDummy(ChartTf::TfToSeconds(PERIOD_CURRENT))); + // 1-second candles. indicators.Add(indi_ama = new Indi_AMA()); + // AMA on platform candles. + indicators.Add(indi_ama_orig_sim = new Indi_AMA()); + + // Original built-in or OnCalculate()-based AMA indicator on platform OHLCs. + indicators.Add(indi_ama_orig = new Indi_AMA()); + // Candles will be initialized from tick's history. indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); + indi_tf_orig_sim.Ptr().SetDataSource(indi_tick.Ptr()); // AMA will work on the candle indicator. indi_ama.Ptr().SetDataSource(indi_tf.Ptr()); + // AMA will work on the simulation of real candles. + indi_ama_orig_sim.Ptr().SetDataSource(indi_tf_orig_sim.Ptr()); + // Checking if there are candles for last 100 ticks. Print(indi_tf.Ptr().GetName(), "'s historic candles (from 100 ticks):"); Print(indi_tf.Ptr().CandlesToString()); @@ -70,7 +86,12 @@ int OnInit() { */ void OnTick() { indicators.Tick(); - Print("Tick: \n" + indicators.ToString(0)); + string o = DoubleToStr(iOpen(_Symbol, PERIOD_CURRENT, 0), 5); + string h = DoubleToStr(iHigh(_Symbol, PERIOD_CURRENT, 0), 5); + string l = DoubleToStr(iLow(_Symbol, PERIOD_CURRENT, 0), 5); + string c = DoubleToStr(iClose(_Symbol, PERIOD_CURRENT, 0), 5); + + Util::Print("Tick: real = " + o + ", " + h + ", " + l + ", " + c + "\n" + indicators.ToString(0)); } /** diff --git a/Indicator/tests/classes/IndicatorTfDummy.h b/Indicator/tests/classes/IndicatorTfDummy.h index fc79a3634..7bd57829e 100644 --- a/Indicator/tests/classes/IndicatorTfDummy.h +++ b/Indicator/tests/classes/IndicatorTfDummy.h @@ -51,6 +51,7 @@ class IndicatorTfDummy : public IndicatorTf { // create/update matching candle. IndicatorTf::OnDataSourceEntry(entry); - Print(GetName(), " got new tick at ", entry.timestamp, ": ", entry.ToString()); + Print(GetFullName(), " got new tick at ", entry.timestamp, + " (" + TimeToString(entry.timestamp) + "): ", entry.ToString()); } }; diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index c3c36269d..f0719417c 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -42,20 +42,23 @@ class IndicatorTickReal : public IndicatorTick SetSymbol(_symbol); } - string GetName() override { return "IndicatorTickDummy"; } + string GetName() override { return "IndicatorTickReal"; } void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { // Feeding base indicator with historic entries of this indicator. - Print(GetName(), " became a data source for ", _base_indi.GetName()); + Print(GetFullName(), " became a data source for ", _base_indi.GetFullName()); int _ticks_to_emit = 100; + Print(_base_indi.GetFullName(), " will be now filled with 100 historical entries generated by " + GetFullName()); + // For testing purposes we are emitting 100 last ticks. for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); TickAB _tick(0.0f, _bid); - EmitEntry(TickToEntry(_timestamp, _tick)); + // We can't call EmitTick() here, as tick would go to multiple sources at the same time! + _base_indi.OnDataSourceEntry(TickToEntry(_timestamp, _tick)); } }; diff --git a/Indicator/tests/classes/Indicators.h b/Indicator/tests/classes/Indicators.h index 2022df473..f8258b555 100644 --- a/Indicator/tests/classes/Indicators.h +++ b/Indicator/tests/classes/Indicators.h @@ -66,7 +66,7 @@ class Indicators { string _result; for (int i = 0; i < ArraySize(_indis); ++i) { IndicatorDataEntry _entry = _indis[i].Ptr().GetEntry(_shift); - _result += _indis[i].Ptr().GetName() + " = " + _entry.ToString() + "\n"; + _result += _indis[i].Ptr().GetFullName() + " = " + _entry.ToString() + "\n"; } return _result; } diff --git a/Util.h b/Util.h index 739fb9f85..e1782d19d 100644 --- a/Util.h +++ b/Util.h @@ -104,6 +104,21 @@ class Util { return _result; } + /** + * Splits prints by newlines on MT4. + */ + static void Print(string _value) { +#ifdef __MQL4__ + string _segments[]; + StringSplit(_value, '\n', _segments); + for (int i = 0; i < ArraySize(_segments); ++i) { + ::Print(_segments[i]); + } +#else + ::Print(_value); +#endif + } + /** * Checks whether array has given value. */ From f92dda0e485020e9db3b074c74f879f5d5a7fb46 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 3 Dec 2021 17:31:06 +0100 Subject: [PATCH 31/81] Probably working scenario of AMA <- IndicatorTfDummy(IndicatorCandle) <- IndicatorTickReal(IndicatorTick) <- platform ticks' ask/bid prices. --- Indicator/IndicatorCandle.h | 10 +++- Indicator/IndicatorTick.h | 66 +++++---------------- Indicator/tests/IndicatorTf.test.mq5 | 32 ++++++---- Indicator/tests/classes/IndicatorTickReal.h | 63 +++++++++++++++----- Indicators/Indi_AMA.mqh | 3 +- 5 files changed, 93 insertions(+), 81 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index e229d0539..34dbc37c6 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -53,6 +53,7 @@ class IndicatorCandle : public IndicatorBase { void Init() { icdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); icdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); + icparams.SetMaxModes(4); } public: @@ -91,7 +92,9 @@ class IndicatorCandle : public IndicatorBase { CandleOCTOHLC _candle = icdata.GetByKey(_candle_time); if (!_candle.IsValid()) { - Print(GetName(), ": Missing candle at shift ", _index, " (", _candle_time, ")"); + Print(GetFullName(), ": Missing candle at shift ", _index, " (", TimeToString(_candle_time), ")"); + } else { + Print(GetFullName(), ": Retrieving candle at shift ", _index, " (", TimeToString(_candle_time), ")"); } return CandleToEntry(_candle_time, _candle); @@ -166,6 +169,9 @@ class IndicatorCandle : public IndicatorBase { void UpdateCandle(long _tick_timestamp, double _price) { long _candle_timestamp = CalcCandleTimestamp(_tick_timestamp); + Print("Updating candle for ", GetFullName(), " at candle ", TimeToString(_candle_timestamp), " from tick at ", + TimeToString(_tick_timestamp)); + CandleOCTOHLC _candle(_price, _price, _price, _price, _tick_timestamp, _tick_timestamp); if (icdata.KeyExists(_candle_timestamp)) { // Candle already exists. @@ -180,7 +186,7 @@ class IndicatorCandle : public IndicatorBase { * Calculates candle's timestamp from tick's timestamp. */ long CalcCandleTimestamp(long _tick_timestamp) { - return _tick_timestamp - _tick_timestamp % (icparams.GetSecsPerCandle() * 1000); + return _tick_timestamp - _tick_timestamp % (icparams.GetSecsPerCandle()); } /** diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 5d7dd0925..4cf53be6b 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -53,6 +53,8 @@ class IndicatorTick : public IndicatorBase { void Init() { itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); itdata.SetOverflowListener(IndicatorTickOverflowListener, 10); + // Ask and Bid price. + itparams.SetMaxModes(2); } public: @@ -106,61 +108,23 @@ class IndicatorTick : public IndicatorBase { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - IndicatorDataEntry GetEntry(int _timestamp = 0) { + IndicatorDataEntry GetEntry(int _timestamp = 0) override { ResetLastError(); - TickAB _entry = itdata.GetByKey(_timestamp); - /* - IndicatorDataEntry _entry = itdata.GetByKey(_timestamp); - if (!_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - _entry.Resize(itparams.GetMaxModes()); - _entry.timestamp = _timestamp; - for (int _mode = 0; _mode < (int)itparams.GetMaxModes(); _mode++) { - switch (itparams.GetDataValueType()) { - case TYPE_BOOL: - case TYPE_CHAR: - case TYPE_INT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_LONG: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_UINT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_ULONG: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_DOUBLE: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_FLOAT: - _entry.values[_mode] = GetValue(_mode, _timestamp); - break; - case TYPE_STRING: - case TYPE_UCHAR: - default: - SetUserError(ERR_INVALID_PARAMETER); - break; - } - } - GetEntryAlter(_entry, _timestamp); - _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, IsValidEntry(_entry)); - if (_entry.IsValid()) { - itdata.Add(_entry, _timestamp); - istate.is_changed = false; - istate.is_ready = true; - } else { - _entry.AddFlags(INDI_ENTRY_FLAG_INSUFFICIENT_DATA); - } + if (itdata.KeyExists(_timestamp)) { + TickAB _tick = itdata.GetByKey(_timestamp); + return TickToEntry(_timestamp, _tick); } - if (_LastError != ERR_NO_ERROR) { - istate.is_ready = false; - ResetLastError(); + + // No tick at given timestamp. Returning invalid entry. + IndicatorDataEntry _entry(itparams.GetMaxModes()); + GetEntryAlter(_entry, _timestamp); + + for (int i = 0; i < itparams.GetMaxModes(); ++i) { + _entry.values[i] = (double)0; } + + _entry.SetFlag(INDI_ENTRY_FLAG_IS_VALID, false); return _entry; - */ - IndicatorDataEntry _foo; - return _foo; } /** diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 7f9aa4d4d..739855fae 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -51,33 +51,36 @@ int OnInit() { indicators.Add(indi_tick = new IndicatorTickReal(_Symbol)); // 1-second candles. - indicators.Add(indi_tf = new IndicatorTfDummy(1)); + // indicators.Add(indi_tf = new IndicatorTfDummy(1)); // 1:1 candles from platform using current timeframe. indicators.Add(indi_tf_orig_sim = new IndicatorTfDummy(ChartTf::TfToSeconds(PERIOD_CURRENT))); // 1-second candles. - indicators.Add(indi_ama = new Indi_AMA()); + // indicators.Add(indi_ama = new Indi_AMA()); + + IndiAMAParams _ama_params; + _ama_params.applied_price = PRICE_OPEN; // AMA on platform candles. - indicators.Add(indi_ama_orig_sim = new Indi_AMA()); + indicators.Add(indi_ama_orig_sim = new Indi_AMA(_ama_params)); // Original built-in or OnCalculate()-based AMA indicator on platform OHLCs. - indicators.Add(indi_ama_orig = new Indi_AMA()); + indicators.Add(indi_ama_orig = new Indi_AMA(_ama_params)); // Candles will be initialized from tick's history. - indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); + // indi_tf.Ptr().SetDataSource(indi_tick.Ptr()); indi_tf_orig_sim.Ptr().SetDataSource(indi_tick.Ptr()); // AMA will work on the candle indicator. - indi_ama.Ptr().SetDataSource(indi_tf.Ptr()); + // indi_ama.Ptr().SetDataSource(indi_tf.Ptr()); // AMA will work on the simulation of real candles. indi_ama_orig_sim.Ptr().SetDataSource(indi_tf_orig_sim.Ptr()); // Checking if there are candles for last 100 ticks. - Print(indi_tf.Ptr().GetName(), "'s historic candles (from 100 ticks):"); - Print(indi_tf.Ptr().CandlesToString()); + // Print(indi_tf.Ptr().GetName(), "'s historic candles (from 100 ticks):"); + // Print(indi_tf.Ptr().CandlesToString()); return (INIT_SUCCEEDED); } @@ -85,13 +88,18 @@ int OnInit() { * Implements OnTick(). */ void OnTick() { - indicators.Tick(); string o = DoubleToStr(iOpen(_Symbol, PERIOD_CURRENT, 0), 5); string h = DoubleToStr(iHigh(_Symbol, PERIOD_CURRENT, 0), 5); string l = DoubleToStr(iLow(_Symbol, PERIOD_CURRENT, 0), 5); string c = DoubleToStr(iClose(_Symbol, PERIOD_CURRENT, 0), 5); + string time = TimeToString(iTime(_Symbol, PERIOD_CURRENT, 0)); + + Util::Print("Tick: " + IntegerToString((long)iTime(_Symbol, PERIOD_CURRENT, 0)) + " (" + time + "), real = " + o + + ", " + h + ", " + l + ", " + c); + + indicators.Tick(); - Util::Print("Tick: real = " + o + ", " + h + ", " + l + ", " + c + "\n" + indicators.ToString(0)); + Util::Print(indicators.ToString(0)); } /** @@ -99,6 +107,6 @@ void OnTick() { */ void OnDeinit(const int reason) { // Printing all grouped candles. - Print(indi_tf.Ptr().GetName(), "'s all candles:"); - Print(indi_tf.Ptr().CandlesToString()); + // Print(indi_tf.Ptr().GetName(), "'s all candles:"); + // Print(indi_tf.Ptr().CandlesToString()); } diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index f0719417c..668ddc1bf 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -29,6 +29,10 @@ #pragma once #endif +// Includes. +#include "../../../Chart.struct.static.h" +#include "../../IndicatorTick.h" + // Params for real tick-based indicator. struct IndicatorTickRealParams : IndicatorParams { IndicatorTickRealParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} @@ -48,25 +52,54 @@ class IndicatorTickReal : public IndicatorTick // Feeding base indicator with historic entries of this indicator. Print(GetFullName(), " became a data source for ", _base_indi.GetFullName()); - int _ticks_to_emit = 100; +#ifndef __MQL4__ + int _ticks_to_emit = 1000; + + Print(_base_indi.GetFullName(), " will be now filled with ", _ticks_to_emit, + " historical entries generated by " + GetFullName()); + + static MqlTick _ticks[]; + ArrayResize(_ticks, 0); + + int _tries = 10; + int _num_copied = -1; + + while (_tries-- > 0) { + _num_copied = CopyTicks(GetSymbol(), _ticks, COPY_TICKS_ALL); - Print(_base_indi.GetFullName(), " will be now filled with 100 historical entries generated by " + GetFullName()); + if (_num_copied == -1) { + Sleep(1000); + } else { + break; + } + } - // For testing purposes we are emitting 100 last ticks. - for (int i = 0; i < MathMin(Bars(GetSymbol(), GetTf()), _ticks_to_emit); ++i) { - long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); - double _bid = ChartStatic::iClose(GetSymbol(), GetTf(), _ticks_to_emit - i - 1); - TickAB _tick(0.0f, _bid); - // We can't call EmitTick() here, as tick would go to multiple sources at the same time! - _base_indi.OnDataSourceEntry(TickToEntry(_timestamp, _tick)); + for (int i = 0; i < _num_copied; ++i) { + TickAB _tick(_ticks[i].ask, _ticks[i].bid); + // We can't call EmitEntry() here, as tick would go to multiple sources at the same time! + _base_indi.OnDataSourceEntry(TickToEntry(_ticks[i].time, _tick)); } - }; +#endif + } void OnTick() override { - long _timestamp = ChartStatic::iTime(GetSymbol(), GetTf()); - double _bid = ChartStatic::iClose(GetSymbol(), GetTf()); - // MT doesn't provide historical ask prices, so we're filling tick with bid price only. - TickAB _tick(_bid, _bid); - EmitEntry(TickToEntry(_timestamp, _tick)); +#ifdef __MQL4__ + // Refreshes Ask/Bid constants. + RefreshRates(); + double _ask = Ask; + double _bid = Bid; + long _time = TimeCurrent(); +#else + static MqlTick _ticks[]; + // Copying only the last tick. + int _num_copied = CopyTicks(GetSymbol(), _ticks, COPY_TICKS_INFO, 0, 1); + + Print("TickReal: ", TimeToString(_ticks[0].time), " = ", _ticks[0].bid); + double _ask = _ticks[0].ask; + double _bid = _ticks[0].bid; + long _time = _ticks[0].time; +#endif + TickAB _tick(_ask, _bid); + EmitEntry(TickToEntry(_time, _tick)); } }; diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 25028689a..861d08cda 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -96,7 +96,8 @@ class Indi_AMA : public Indicator { int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, _ap, - Util::MakeKey("INDI_AMA", _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, (int)_ap)); + Util::MakeKey("INDI_AMA_ON_" + _indi.GetFullName(), _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, + (int)_ap)); return iAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, _mode, _shift, _cache); } From 6f3b99adf73f78fa33de91f440b1827c59af5c88 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 3 Dec 2021 18:35:00 +0100 Subject: [PATCH 32/81] Fixed Util::ArrayRemove() method. --- Util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Util.h b/Util.h index e1782d19d..904fde211 100644 --- a/Util.h +++ b/Util.h @@ -74,7 +74,7 @@ class Util { // Index out of array bounds. return false; } - for (int i = index; i < ArraySize(_array); ++i) { + for (int i = index; i < ArraySize(_array) - 1; ++i) { _array[i] = _array[i + 1]; } Util::ArrayResize(_array, ArraySize(_array) - 1); From 28bc1e9a6c0b9579795a4b3b2e170f076229a456 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 5 Dec 2021 14:48:19 +0000 Subject: [PATCH 33/81] Account/SymbolInfo: Adds copy constructors --- Account.mqh | 5 +++++ SymbolInfo.mqh | 5 +++++ SymbolInfo.struct.h | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Account.mqh b/Account.mqh index 737b62f28..57acce602 100644 --- a/Account.mqh +++ b/Account.mqh @@ -63,6 +63,11 @@ class Account { */ Account() : init_balance(CalcInitDeposit()), start_balance(GetBalance()), start_credit(GetCredit()) {} + /** + * Class copy constructor. + */ + Account(const Account &_account) {} + /** * Class deconstructor. */ diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh index a277b0c8c..259050095 100644 --- a/SymbolInfo.mqh +++ b/SymbolInfo.mqh @@ -73,6 +73,11 @@ class SymbolInfo : public Object { } } + /** + * Class copy constructor. + */ + SymbolInfo(const SymbolInfo &_si) : s_entry(_si.s_entry), sprops(_si.sprops) {} + ~SymbolInfo() {} /** diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index ba2dc565d..e6c1cb1e7 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -46,7 +46,7 @@ struct SymbolInfoEntry double last; // Price of the last deal. double spread; // Current spread. unsigned long volume; // Volume for the current last price. - // Constructor. + // Constructors. SymbolInfoEntry() : bid(0), ask(0), last(0), spread(0), volume(0) {} SymbolInfoEntry(const MqlTick& _tick, const string _symbol = "") { bid = _tick.bid; @@ -55,6 +55,7 @@ struct SymbolInfoEntry volume = _tick.volume; spread = (unsigned int)round((ask - bid) * pow(10, SymbolInfoStatic::SymbolInfoInteger(_symbol, SYMBOL_DIGITS))); } + SymbolInfoEntry(const SymbolInfoEntry& _sie) {} // Getters string ToCSV() { return StringFormat("%g,%g,%g,%g,%d", bid, ask, last, spread, volume); } // Serializers. @@ -72,6 +73,9 @@ struct SymbolInfoProp { unsigned int pip_digits; // Pip digits (precision). unsigned int pts_per_pip; // Points per pip. unsigned int vol_digits; // Volume digits. + // Constructors. + SymbolInfoProp() {} + SymbolInfoProp(const SymbolInfoProp& _sip) {} // Serializers. void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {} SerializerNodeType Serialize(Serializer& _s); From 3871dd8e5f3cc21fef73273a28d31f7a85af50b8 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 5 Dec 2021 14:54:23 +0000 Subject: [PATCH 34/81] Adds Exchange class and tests --- .github/workflows/test-exchange.yml | 62 +++++++++++++++++++++++++++++ Exchange/Exchange.h | 57 ++++++++++++++++++++++++++ Exchange/Exchange.struct.h | 42 +++++++++++++++++++ Exchange/tests/Exchange.test.mq4 | 28 +++++++++++++ Exchange/tests/Exchange.test.mq5 | 37 +++++++++++++++++ 5 files changed, 226 insertions(+) create mode 100644 .github/workflows/test-exchange.yml create mode 100644 Exchange/Exchange.h create mode 100644 Exchange/Exchange.struct.h create mode 100644 Exchange/tests/Exchange.test.mq4 create mode 100644 Exchange/tests/Exchange.test.mq5 diff --git a/.github/workflows/test-exchange.yml b/.github/workflows/test-exchange.yml new file mode 100644 index 000000000..b4c0ed3c9 --- /dev/null +++ b/.github/workflows/test-exchange.yml @@ -0,0 +1,62 @@ +--- +name: Test Exchange + +# yamllint disable-line rule:truthy +on: + pull_request: + paths: + - 'Exchange/**.h' + - 'Exchange/**.mq?' + - '.github/workflows/test-exchange.yml' + push: + paths: + - 'Exchange/**.h' + - 'Exchange/**.mq?' + - '.github/workflows/test-exchange.yml' + +jobs: + + Compile: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Compile + uses: fx31337/mql-compile-action@master + with: + init-platform: true + path: 'Exchange/tests' + verbose: true + - name: Print compiled files + run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' + shell: powershell + - name: Upload artifacts (MQL4) + uses: actions/upload-artifact@v2 + with: + name: files-ex4 + path: '**/*.ex4' + - name: Upload artifacts (MQL5) + uses: actions/upload-artifact@v2 + with: + name: files-ex5 + path: '**/*.ex5' + + Exchange-Tests-MQL4: + defaults: + run: + shell: bash + working-directory: Exchange/tests + needs: Compile + runs-on: ubuntu-latest + strategy: + matrix: + test: + - Exchange.test + steps: + - uses: actions/download-artifact@v2 + with: + name: files-ex4 + - name: Run ${{ matrix.test }} + uses: fx31337/mql-tester-action@master + with: + Script: ${{ matrix.test }} + timeout-minutes: 10 diff --git a/Exchange/Exchange.h b/Exchange/Exchange.h new file mode 100644 index 000000000..c252ccfab --- /dev/null +++ b/Exchange/Exchange.h @@ -0,0 +1,57 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +/** + * Exchange class. + */ +#ifndef EXCHANGE_H +#define EXCHANGE_H + +// Includes. +#include "../Account.mqh" +#include "../DictObject.mqh" +#include "../SymbolInfo.mqh" +#include "Exchange.struct.h" + +class Exchange { + protected: + DictObject accounts; + DictObject symbols; + ExchangeParams eparams; + + public: + /** + * Class constructor without parameters. + */ + Exchange(){}; + + /** + * Class constructor with parameters. + */ + Exchange(ExchangeParams &_eparams) : eparams(_eparams){}; + + /** + * Class deconstructor. + */ + ~Exchange() {} +}; +#endif // EXCHANGE_H diff --git a/Exchange/Exchange.struct.h b/Exchange/Exchange.struct.h new file mode 100644 index 000000000..d63290d4f --- /dev/null +++ b/Exchange/Exchange.struct.h @@ -0,0 +1,42 @@ +//+------------------------------------------------------------------+ +//| 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 + * Includes Exchange's structs. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Forward class declaration. +class Exchange; + +/* Defines struct for Exchange parameters. */ +struct ExchangeParams { + // Constructors. + ExchangeParams() {} + ExchangeParams(const ExchangeParams &_eparams) {} + long id; +}; diff --git a/Exchange/tests/Exchange.test.mq4 b/Exchange/tests/Exchange.test.mq4 new file mode 100644 index 000000000..2b3fdf2da --- /dev/null +++ b/Exchange/tests/Exchange.test.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of Exchange class. + */ + +// Includes. +#include "Exchange.test.mq5" diff --git a/Exchange/tests/Exchange.test.mq5 b/Exchange/tests/Exchange.test.mq5 new file mode 100644 index 000000000..2eddca405 --- /dev/null +++ b/Exchange/tests/Exchange.test.mq5 @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test functionality of Exchange class. + */ + +// Includes. +#include "../../Test.mqh" +#include "../Exchange.h" + +/** + * Implements OnInit(). + */ +int OnInit() { + bool _result = true; + return _result && GetLastError() == ERR_NO_ERROR ? INIT_SUCCEEDED : INIT_FAILED; +} From 3f09d09b51b363a22d2372b8567ae7a912215c54 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 5 Dec 2021 15:05:11 +0000 Subject: [PATCH 35/81] Exchange: Adds Trade --- Exchange/Exchange.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Exchange/Exchange.h b/Exchange/Exchange.h index c252ccfab..cce5009c6 100644 --- a/Exchange/Exchange.h +++ b/Exchange/Exchange.h @@ -30,12 +30,14 @@ #include "../Account.mqh" #include "../DictObject.mqh" #include "../SymbolInfo.mqh" +#include "../Trade.mqh" #include "Exchange.struct.h" class Exchange { protected: DictObject accounts; DictObject symbols; + DictObject trades; ExchangeParams eparams; public: @@ -53,5 +55,6 @@ class Exchange { * Class deconstructor. */ ~Exchange() {} + }; #endif // EXCHANGE_H From 92bb33449fed3a8841ece764d8ecaed116e429d3 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 5 Dec 2021 15:30:36 +0000 Subject: [PATCH 36/81] SymbolInfo: Adds class constructor with symbol properties --- SymbolInfo.mqh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh index 259050095..61da0d116 100644 --- a/SymbolInfo.mqh +++ b/SymbolInfo.mqh @@ -57,8 +57,9 @@ class SymbolInfo : public Object { double volume_precision; public: + /** - * Implements class constructor with a parameter. + * Class constructor given a symbol string. */ SymbolInfo(string _symbol = NULL) : symbol(_symbol), pip_size(GetPipSize()), symbol_digits(GetDigits()) { Select(); @@ -73,6 +74,11 @@ class SymbolInfo : public Object { } } + /** + * Class constructor with symbol properties. + */ + SymbolInfo(const SymbolInfoProp &_sip) : sprops(_sip) {} + /** * Class copy constructor. */ From 78323e0e38acdd9ea14b2809218b09e569d1070d Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 5 Dec 2021 15:31:43 +0000 Subject: [PATCH 37/81] Exchange: Adds methods to add/remove account and symbol --- Exchange/Exchange.h | 23 +++++++++++++++++++++++ Exchange/tests/Exchange.test.mq5 | 6 ++++++ SymbolInfo.mqh | 1 - 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Exchange/Exchange.h b/Exchange/Exchange.h index cce5009c6..85b9e9202 100644 --- a/Exchange/Exchange.h +++ b/Exchange/Exchange.h @@ -56,5 +56,28 @@ class Exchange { */ ~Exchange() {} + /* Adders */ + + /** + * Adds account to the list. + */ + void AccountAdd(Account &_account, string _name) { accounts.Set(_name, _account); } + + /** + * Adds symbol to the list. + */ + void SymbolAdd(SymbolInfo &_sinfo, string _name) { symbols.Set(_name, _sinfo); } + + /* Removers */ + + /** + * Removes account from the list. + */ + void AccountRemove(string _name) { accounts.Unset(_name); } + + /** + * Removes symbol from the list. + */ + void SymbolRemove(string _name) { symbols.Unset(_name); } }; #endif // EXCHANGE_H diff --git a/Exchange/tests/Exchange.test.mq5 b/Exchange/tests/Exchange.test.mq5 index 2eddca405..1c9d1c39b 100644 --- a/Exchange/tests/Exchange.test.mq5 +++ b/Exchange/tests/Exchange.test.mq5 @@ -28,6 +28,12 @@ #include "../../Test.mqh" #include "../Exchange.h" +// Test classes. +class ExchangeDummy : public Exchange {}; + +// Global variables. +ExchangeDummy ex_dummy; + /** * Implements OnInit(). */ diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh index 61da0d116..8ac319832 100644 --- a/SymbolInfo.mqh +++ b/SymbolInfo.mqh @@ -57,7 +57,6 @@ class SymbolInfo : public Object { double volume_precision; public: - /** * Class constructor given a symbol string. */ From 9603dc3b15bc7c85848c374322fd0b2671d2d26b Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 7 Dec 2021 19:19:37 +0100 Subject: [PATCH 38/81] WIP. i*OnIndicator versions of all indicators (except MA). --- Indicator.enum.h | 12 ++++++ IndicatorBase.h | 30 +++++++++++++++ Indicators/Indi_ADXW.mqh | 10 +++++ Indicators/Indi_AMA.mqh | 30 +++++++-------- Indicators/Indi_ASI.mqh | 10 +++++ Indicators/Indi_BWZT.mqh | 34 ++++++++++++++++- Indicators/Indi_CHO.mqh | 16 +++++++- Indicators/Indi_CHV.mqh | 13 +++++++ Indicators/Indi_ColorBars.mqh | 12 +++++- Indicators/Indi_ColorCandlesDaily.mqh | 10 +++++ Indicators/Indi_ColorLine.mqh | 26 +++++++++++++ Indicators/Indi_DEMA.mqh | 52 +++++++++++++++----------- Indicators/Indi_DetrendedPrice.mqh | 16 ++++++-- Indicators/Indi_FractalAdaptiveMA.mqh | 15 +++++++- Indicators/Indi_HeikenAshi.mqh | 10 +++++ Indicators/Indi_MassIndex.mqh | 13 +++++++ Indicators/Indi_PriceChannel.mqh | 12 +++++- Indicators/Indi_PriceVolumeTrend.mqh | 10 +++++ Indicators/Indi_RateOfChange.mqh | 10 +++++ Indicators/Indi_TEMA.mqh | 12 ++++++ Indicators/Indi_TRIX.mqh | 10 +++++ Indicators/Indi_UltimateOscillator.mqh | 20 ++++++++++ Indicators/Indi_VIDYA.mqh | 13 +++++++ Indicators/Indi_VROC.mqh | 12 +++++- Indicators/Indi_Volumes.mqh | 12 +++++- Indicators/Indi_WilliamsAD.mqh | 10 +++++ Indicators/Indi_ZigZag.mqh | 12 ++++++ Indicators/Indi_ZigZagColor.mqh | 13 +++++++ Storage/ValueStorage.h | 11 ++++++ 29 files changed, 419 insertions(+), 47 deletions(-) diff --git a/Indicator.enum.h b/Indicator.enum.h index 63baad455..e67e3ff88 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -228,3 +228,15 @@ enum INDICATOR_ENTRY_FLAGS { INDI_ENTRY_FLAG_IS_VALID = 1 << 6, INDI_ENTRY_FLAG_INSUFFICIENT_DATA = 1 << 7, // Entry has missing value for that shift and probably won't ever have. }; + +// Storage type for IndicatorBase::GetSpecificValueStorage(). +enum ENUM_INDI_VS_TYPE { + INDI_VS_TYPE_TIME, + INDI_VS_TYPE_TICK_VOLUME, + INDI_VS_TYPE_VOLUME, + INDI_VS_TYPE_SPREAD, + INDI_VS_TYPE_PRICE_OPEN, + INDI_VS_TYPE_PRICE_HIGH, + INDI_VS_TYPE_PRICE_LOW, + INDI_VS_TYPE_PRICE_CLOSE +}; \ No newline at end of file diff --git a/IndicatorBase.h b/IndicatorBase.h index d1f61d607..a0bed2b73 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -275,6 +275,27 @@ class IndicatorBase : public Chart { */ IndicatorBase* GetDataSourceRaw() { return indi_src.Ptr(); } + /** + * Returns given data source type. Used by i*OnIndicator methods if indicator's Calculate() uses other indicators. + */ + IndicatorBase* GetDataSource(ENUM_INDICATOR_TYPE _type) { + IndicatorBase* _result = NULL; + if (indicators.KeyExists((int)_type)) { + _result = indicators[(int)_type].Ptr(); + } else { + Ref _indi = FetchDataSource(_type); + if (!_indi.IsSet()) { + Alert(GetFullName(), " does not define required indicator type ", EnumToString(_type), " for symbol ", + GetSymbol(), ", and timeframe ", GetTf(), "!"); + DebugBreak(); + } else { + indicators.Set((int)_type, _indi); + _result = _indi.Ptr(); + } + } + return _result; + } + /* Getters */ /** @@ -423,6 +444,15 @@ class IndicatorBase : public Chart { return value_storages[_mode]; } + /** + * Returns value storage of given kind. + */ + virtual IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { + Print("Error: ", GetFullName(), " indicator has no storage type ", EnumToString(_type), "!"); + DebugBreak(); + return NULL; + } + template T GetValue(int _index = 0, int _mode = 0) { T _out; diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index efd22ce2e..b8142fd78 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -102,6 +102,16 @@ class Indi_ADXW : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of ADX Wilder. + */ + static double iADXWilderOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_ADXW_ON_" + _indi.GetFullName(), _period)); + return iADXWilderOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _mode, _shift, _cache); + } + /** * OnCalculate() method for ADXW indicator. */ diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 861d08cda..d71d33756 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -82,26 +82,12 @@ class Indi_AMA : public Indicator { #else INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT( _symbol, _tf, _ap, - Util::MakeKey("INDI_AMA", _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, (int)_ap)); + Util::MakeKey("Indi_AMA", _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, (int)_ap)); return iAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, _mode, _shift, _cache); #endif } - /** - * On-indicator version of AMA. - */ - static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, - int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { - INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( - _indi, _symbol, _tf, _ap, - Util::MakeKey("INDI_AMA_ON_" + _indi.GetFullName(), _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, - (int)_ap)); - return iAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ama_period, _fast_ema_period, _slow_ema_period, - _ama_shift, _mode, _shift, _cache); - } - /** * Calculates AMA on the array of values. */ @@ -124,6 +110,20 @@ class Indi_AMA : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of AMA. + */ + static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, + int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, + Util::MakeKey("Indi_AMA_ON_" + _indi.GetFullName(), _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, + (int)_ap)); + return iAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ama_period, _fast_ema_period, _slow_ema_period, + _ama_shift, _mode, _shift, _cache); + } + /** * OnInit() method for AMA indicator. */ diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 2e0cf341b..1e9f54281 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -84,6 +84,16 @@ class Indi_ASI : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of ASI. + */ + static double iASIOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_ASI_ON_" + _indi.GetFullName(), _mpc)); + return iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mpc, _mode, _shift, _cache); + } + /** * OnInit() method for ASI indicator. */ diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 65d7cb881..08405e14f 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTf.h" #include "../Storage/ValueStorage.all.h" #include "Indi_AC.mqh" #include "Indi_AO.mqh" @@ -40,11 +40,15 @@ enum ENUM_INDI_BWZT_MODE { // Structs. struct IndiBWZTParams : IndicatorParams { + Indi_AC *indi_ac; + Indi_AC *indi_ao; unsigned int period; unsigned int second_period; unsigned int sum_period; // Struct constructor. IndiBWZTParams(int _shift = 0) : IndicatorParams(INDI_BWZT, FINAL_INDI_BWZT_MODE_ENTRY, TYPE_DOUBLE) { + indi_ac = NULL; + indi_ao = NULL; SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\BW-ZoneTrade"); shift = _shift; @@ -102,6 +106,34 @@ class Indi_BWZT : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of BWZT. + */ + static double iBWZTOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode, + int _shift, IndicatorBase *_obj) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_BWZT_ON_" + _indi.GetFullName())); + + Indi_AC *_indi_ac = _obj.GetDataSource(INDI_AC); + Indi_AO *_indi_ao = _obj.GetDataSource(INDI_AO); + + return iBWZTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache, _indi_ac, _indi_ao); + } + + /** + * Provides built-in indicators whose can be used as data source. + */ + virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { + switch (_id) { + case INDI_AC: + return iparams.indi_ac; + case INDI_AO: + return iparams.indi_ac; + } + + return NULL; + } + /** * OnCalculate() method for BWZT indicator. */ diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index 1cf24699e..6106dbefe 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -73,7 +73,7 @@ class Indi_CHO : public Indicator { _mode, _shift); #else INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG( - _symbol, _tf, Util::MakeKey("INDI_CHO", _fast_ma_period, _slow_ma_period, (int)_ma_method, (int)_av)); + _symbol, _tf, Util::MakeKey("Indi_CHO", _fast_ma_period, _slow_ma_period, (int)_ma_method, (int)_av)); return iChaikinOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _fast_ma_period, _slow_ma_period, _ma_method, _av, _mode, _shift, _cache); #endif @@ -102,6 +102,20 @@ class Indi_CHO : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Chaikin Oscillator. + */ + static double iChaikinOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _fast_ma_period, + int _slow_ma_period, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_VOLUME _av, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, + Util::MakeKey("Indi_CHO_ON_" + _indi.GetFullName(), _fast_ma_period, _slow_ma_period, (int)_ma_method, + (int)_av)); + return iChaikinOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _fast_ma_period, _slow_ma_period, _ma_method, _av, + _mode, _shift, _cache); + } + /** * OnCalculate() method for Chaikin Oscillator indicator. */ diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index d3f97fd42..8b8f9490e 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -99,6 +99,19 @@ class Indi_CHV : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Chaikin Volatility. + */ + static double iCHVOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _smooth_period, + int _chv_period, ENUM_CHV_SMOOTH_METHOD _smooth_method, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, + Util::MakeKey("Indi_CHV_ON_" + _indi.GetFullName(), _smooth_period, _chv_period, _smooth_method)); + return iCHVOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _smooth_period, _chv_period, _smooth_method, _mode, + _shift, _cache); + } + /** * OnInit() method for Chaikin Volatility indicator. */ diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index f89773c19..676a91767 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -56,7 +56,7 @@ class Indi_ColorBars : public Indicator { */ static double iColorBars(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { - INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_ColorCandlesDaily"); + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_ColorBars"); return iColorBarsOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); } @@ -82,6 +82,16 @@ class Indi_ColorBars : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Color Bars. + */ + static double iColorBarsOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_ColorBars_ON_" + _indi.GetFullName())); + return iColorBarsOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); + } + /** * OnCalculate() method for Color Bars indicator. */ diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index b8c4b851c..1515cdc45 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -82,6 +82,16 @@ class Indi_ColorCandlesDaily : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Color Candles Daily. + */ + static double iCCDOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_ColorCandlesDaily_ON_" + _indi.GetFullName())); + return iCCDOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); + } + /** * OnCalculate() method for Color Candles Daily indicator. */ diff --git a/Indicators/Indi_ColorLine.mqh b/Indicators/Indi_ColorLine.mqh index d3dd60ed7..886c70737 100644 --- a/Indicators/Indi_ColorLine.mqh +++ b/Indicators/Indi_ColorLine.mqh @@ -28,8 +28,10 @@ // Structs. struct IndiColorLineParams : IndicatorParams { + IndicatorBase *indi_ma; // Struct constructor. IndiColorLineParams(int _shift = 0) : IndicatorParams(INDI_COLOR_LINE, 2, TYPE_DOUBLE) { + indi_ma = NULL; SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorLine"); shift = _shift; @@ -86,6 +88,30 @@ class Indi_ColorLine : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Color Line. + */ + static double iColorLineOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_ColorLine_ON_" + _indi.GetFullName())); + + Indi_MA *_indi_ma = _obj.GetDataSource(INDI_MA); + + return iColorLineOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache, _indi_ma); + } + + /** + * Provides built-in indicators whose can be used as data source. + */ + virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { + switch (_id) { + case INDI_MA: + return iparams.indi_ma; + } + return NULL; + } + /** * OnCalculate() method for Color Line indicator. */ diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index 420034607..e89f07723 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -108,44 +108,54 @@ class Indi_DEMA : public Indicator { #else Indi_Price *_indi_price = Indi_Price::GetCached(_symbol, _applied_price, _tf, _shift); // Note that _applied_price and Indi_Price mode indices are compatible. - return Indi_DEMA::iDEMAOnIndicator(_indi_price.GetCache(), _indi_price, 0, _period, _ma_shift, _shift); + return Indi_DEMA::iDEMAOnIndicatorSlow(_indi_price.GetCache(), _indi_price, 0, _period, _ma_shift, _shift); #endif } - static double iDEMAOnIndicator(IndicatorCalculateCache *cache, IndicatorBase *_indi, int indi_mode, - unsigned int ma_period, unsigned int ma_shift, int shift) { + static double iDEMAOnIndicatorSlow(IndicatorCalculateCache *cache, IndicatorBase *_indi, int indi_mode, + unsigned int ma_period, unsigned int ma_shift, int shift) { return iDEMAOnArray(_indi.GetValueStorage(indi_mode), 0, ma_period, ma_shift, shift, cache); } - static double iDEMAOnArray(ValueStorage &price, int total, unsigned int ma_period, unsigned int ma_shift, - int shift, IndicatorCalculateCache *cache = NULL, bool recalculate = false) { - if (cache == NULL) { + static double iDEMAOnArray(INDICATOR_CALCULATE_PARAMS_SHORT, unsigned int _ma_period, unsigned int _ma_shift, + int _mode, int _shift, IndicatorCalculateCache *_cache = NULL, + bool _recalculate = false) { + if (_cache == NULL) { Print("iDEMAOnArray() cannot yet work without cache object!"); DebugBreak(); return 0.0f; } - cache.SetPriceBuffer(price); + _cache.SetPriceBuffer(_price); - if (!cache.HasBuffers()) { - cache.AddBuffer>(3); // 3 buffers. + if (!_cache.HasBuffers()) { + _cache.AddBuffer>(3); // 3 buffers. } - if (recalculate) { + if (_recalculate) { // We don't want to continue calculations, but to recalculate previous one. - cache.ResetPrevCalculated(); + _cache.ResetPrevCalculated(); } - cache.SetPrevCalculated(Indi_DEMA::Calculate(cache.GetTotal(), cache.GetPrevCalculated(), 0, cache.GetPriceBuffer(), - ma_period, cache.GetBuffer(0), cache.GetBuffer(1), - cache.GetBuffer(2))); + _cache.SetPrevCalculated(Indi_DEMA::Calculate(INDICATOR_CALCULATE_GET_PARAMS_SHORT, _cache.GetBuffer(0), + _cache.GetBuffer(1), _cache.GetBuffer(2), + _ma_period)); - return cache.GetTailValue(0, ma_shift + shift); + return _cache.GetTailValue(0, _ma_shift + _shift); } - static int Calculate(const int rates_total, const int prev_calculated, const int begin, ValueStorage &price, - int InpPeriodEMA, ValueStorage &DemaBuffer, ValueStorage &Ema, - ValueStorage &EmaOfEma) { + /** + * On-indicator version of DEMA. + */ + static double iDEMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, int _ma_shift, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, (int)_ap, Util::MakeKey("Indi_CHV_ON_" + _indi.GetFullName(), _period, _ma_shift)); + return iDEMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _ma_shift, _mode, _shift, _cache); + } + + static int Calculate(INDICATOR_CALCULATE_METHOD_PARAMS_SHORT, ValueStorage &DemaBuffer, + ValueStorage &Ema, ValueStorage &EmaOfEma, int InpPeriodEMA) { if (rates_total < 2 * InpPeriodEMA - 2) return (0); int start; @@ -176,7 +186,7 @@ class Indi_DEMA : public Indicator { istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; _value = Indi_DEMA::iDEMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetAppliedPrice(), _ishift, _mode, - GetPointer(this)); + THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; @@ -185,8 +195,8 @@ class Indi_DEMA : public Indicator { break; case IDATA_INDICATOR: // Calculating DEMA value from specified indicator. - _value = Indi_DEMA::iDEMAOnIndicator(GetCache(), GetDataSource(), GetDataSourceMode(), GetPeriod(), - GetMAShift(), _ishift); + _value = Indi_DEMA::iDEMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), + GetAppliedPrice(), _mode, _ishift, THIS_PTR); break; } return _value; diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index b8c4fe1cd..ef34a7391 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -65,14 +65,14 @@ class Indi_DetrendedPrice : public Indicator { int _shift = 0, IndicatorBase *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT(_symbol, _tf, _ap, Util::MakeKey("Indi_DPO", _period, (int)_ap)); - return iDPOOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _mode, _shift, _cache); + return iDPOOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _ap, _mode, _shift, _cache); } /** * Calculates DPO on the array of values. */ - static double iDPOOnArray(INDICATOR_CALCULATE_PARAMS_SHORT, int _period, int _mode, int _shift, - IndicatorCalculateCache *_cache, bool _recalculate = false) { + static double iDPOOnArray(INDICATOR_CALCULATE_PARAMS_SHORT, int _period, ENUM_APPLIED_PRICE _ap, int _mode, + int _shift, IndicatorCalculateCache *_cache, bool _recalculate = false) { _cache.SetPriceBuffer(_price); if (!_cache.HasBuffers()) { @@ -89,6 +89,16 @@ class Indi_DetrendedPrice : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of DPO. + */ + static double iDPOOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_DPO_ON_" + _indi.GetFullName(), _period, (int)_ap)); + return iDPOOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _ap, _mode, _shift, _cache); + } + /** * OnCalculate() method for DPO indicator. */ diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 7640170c0..67dc21173 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -76,8 +76,8 @@ class Indi_FrAMA : public Indicator { /** * Calculates FrAMA on the array of values. */ - static double iFrAMAOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _ma_period, int _ma_shift, int _mode, int _shift, - ENUM_APPLIED_PRICE _ap, IndicatorCalculateCache *_cache, + static double iFrAMAOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _ma_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, + int _mode, int _shift, IndicatorCalculateCache *_cache, bool _recalculate = false) { _cache.SetPriceBuffer(_open, _high, _low, _close); @@ -95,6 +95,17 @@ class Indi_FrAMA : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of FrAMA. + */ + static double iFrAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_AMA_ON_" + _indi.GetFullName(), _ma_period, _ma_shift, (int)_ap)); + return iFrAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _ma_period, _ma_shift, _ap, _mode, _shift, _cache); + } + static int Calculate(INDICATOR_CALCULATE_METHOD_PARAMS_LONG, ValueStorage &FrAmaBuffer, int InpPeriodFrAMA, int InpShift, ENUM_APPLIED_PRICE InpAppliedPrice) { if (rates_total < 2 * InpPeriodFrAMA) return (0); diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 789478852..5239c1790 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -157,6 +157,16 @@ class Indi_HeikenAshi : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Heiken Ashi. + */ + static double iHeikenAshiOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_HeikenAshi_ON_" + _indi.GetFullName())); + return iHeikenAshiOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); + } + /** * OnCalculate() method for Mass Index indicator. */ diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 817b81cd8..1e0076f55 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -92,6 +92,19 @@ class Indi_MassIndex : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Mass Index. + */ + static double iMIOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + int _second_period, int _sum_period, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, + Util::MakeKey("Indi_MassIndex_ON_" + _indi.GetFullName(), _period, _second_period, _sum_period)); + return iMIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _second_period, _sum_period, _mode, _shift, + _cache); + } + /** * OnCalculate() method for Mass Index indicator. */ diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index 0afc2392e..415082498 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -43,7 +43,7 @@ struct IndiPriceChannelParams : IndicatorParams { }; /** - * Implements the Bill Williams' Accelerator/Decelerator oscillator. + * Implements Price Channel indicator. */ class Indi_PriceChannel : public Indicator { public: @@ -86,6 +86,16 @@ class Indi_PriceChannel : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Price Channel. + */ + static double iPriceChannelOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_PriceChannel_ON_" + _indi.GetFullName(), _period)); + return iPriceChannelOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _mode, _shift, _cache); + } + /** * OnCalculate() method for Price Channel indicator. */ diff --git a/Indicators/Indi_PriceVolumeTrend.mqh b/Indicators/Indi_PriceVolumeTrend.mqh index 17505eff1..ecf0ae493 100644 --- a/Indicators/Indi_PriceVolumeTrend.mqh +++ b/Indicators/Indi_PriceVolumeTrend.mqh @@ -85,6 +85,16 @@ class Indi_PriceVolumeTrend : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Price Volume Trend. + */ + static double iPVTOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_APPLIED_VOLUME _av, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_PVT_ON_" + _indi.GetFullName(), (int)_av)); + return iPVTOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _av, _mode, _shift, _cache); + } + /** * OnCalculate() method for Price Volume Trend indicator. */ diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index 076f4798a..fd597bbe0 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -88,6 +88,16 @@ class Indi_RateOfChange : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Rate of Change. + */ + static double iROCOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_RateOfChange_ON_" + _indi.GetFullName(), _period, (int)_ap)); + return iROCOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _mode, _shift, _cache); + } + /** * OnCalculate() method for Rate of Change indicator. */ diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 3cc9e949b..626ad9186 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -94,6 +94,18 @@ class Indi_TEMA : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of TEMA. + */ + static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, + Util::MakeKey("Indi_TEMA_ON_" + _indi.GetFullName(), _ma_period, _ma_shift, (int)_ap)); + return iTEMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ma_period, _ma_shift, _mode, _shift, _cache); + } + /** * OnCalculate() method for TEMA indicator. * diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index a8086bd27..da77f4e33 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -93,6 +93,16 @@ class Indi_TRIX : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of TriX. + */ + static double iTriXOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_TriX_ON_" + _indi.GetFullName(), _ma_period, (int)_ap)); + return iTriXOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ma_period, _mode, _shift, _cache); + } + /** * OnCalculate() method for TriX indicator. */ diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index 7788bd77b..ee6782641 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -113,6 +113,26 @@ class Indi_UltimateOscillator : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Ultimate Oscillator. + */ + static double iUOOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _fast_period, + int _middle_period, int _slow_period, int _fast_k, int _middle_k, int _slow_k, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, + Util::MakeKey("Indi_UltimateOscillator_ON_" + _indi.GetFullName(), _fast_period, _middle_period, _slow_period, + _fast_k, _middle_k, _slow_k)); + + // @fixit This won't work! Find a way to differentiate ATRs. + Indi_ATR *_indi_atr_fast = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); + Indi_ATR *_indi_atr_middle = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); + Indi_ATR *_indi_atr_slow = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); + + return iUOOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _fast_period, _middle_period, _slow_period, _fast_k, + _middle_k, _slow_k, _mode, _shift, _cache, _indi_atr_fast, _indi_atr_middle, _indi_atr_slow); + } + /** * OnCalculate() method for Ultimate Oscillator. */ diff --git a/Indicators/Indi_VIDYA.mqh b/Indicators/Indi_VIDYA.mqh index a5647974c..15f959e15 100644 --- a/Indicators/Indi_VIDYA.mqh +++ b/Indicators/Indi_VIDYA.mqh @@ -98,6 +98,19 @@ class Indi_VIDYA : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of VIDya indicator. + */ + static double iVIDyAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _cmo_period, + int _ema_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + _indi, _symbol, _tf, _ap, + Util::MakeKey("Indi_VIDYA_ON_" + _indi.GetFullName(), _cmo_period, _ema_period, _ma_shift, (int)_ap)); + return iVIDyAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _cmo_period, _ema_period, _ma_shift, _mode, _shift, + _cache); + } + /** * OnCalculate() method for VIDyA indicator. * diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index 2170fa831..dfad54d06 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -65,7 +65,7 @@ class Indi_VROC : public Indicator { } /** - * Calculates AMVROC on the array of values. + * Calculates VROC on the array of values. */ static double iVROCOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _period, ENUM_APPLIED_VOLUME _av, int _mode, int _shift, IndicatorCalculateCache *_cache, bool _recalculate = false) { @@ -85,6 +85,16 @@ class Indi_VROC : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of VROC indicator. + */ + static double iVROCOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + ENUM_APPLIED_VOLUME _av, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_VROC_ON_" + _indi.GetFullName(), _period, (int)_av)); + return iVROCOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _av, _mode, _shift, _cache); + } + /** * OnCalculate() method for VROC indicator. */ diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 786f9fbbe..4fb2a2888 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -44,7 +44,7 @@ struct IndiVolumesParams : IndicatorParams { }; /** - * Implements the Bill Williams' Accelerator/Decelerator oscillator. + * Implements the Volumes indicator. */ class Indi_Volumes : public Indicator { public: @@ -84,6 +84,16 @@ class Indi_Volumes : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Volumes indicator. + */ + static double iVolumesOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_APPLIED_VOLUME _av, + int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_Volumes_ON_" + _indi.GetFullName(), (int)_av)); + return iVolumesOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _av, _mode, _shift, _cache); + } + /** * OnCalculate() method for Volumes indicator. */ diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 754cff808..36b56685b 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -80,6 +80,16 @@ class Indi_WilliamsAD : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of Williams' AD. + */ + static double iWADOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, + Util::MakeKey("Indi_WilliamsAD_ON_" + _indi.GetFullName())); + return iWADOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); + } + /** * OnCalculate() method for Williams' AD indicator. */ diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 94fa26e33..e79ca128c 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -135,6 +135,18 @@ class Indi_ZigZag : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of ZigZag indicator. + */ + static double iZigZagOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _depth, + int _deviation, int _backstep, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, Util::MakeKey("Indi_ZigZag_ON_" + _indi.GetFullName(), _depth, _deviation, _backstep)); + return iZigZagOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _depth, _deviation, _backstep, _mode, _shift, + _cache); + } + /** * OnCalculate() method for ZigZag indicator. */ diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index 26489fd8f..f30004ebb 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -96,6 +96,19 @@ class Indi_ZigZagColor : public Indicator { return _cache.GetTailValue(_mode, _shift); } + /** + * On-indicator version of ZigZag indicator. + */ + static double iZigZagColorOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _depth, + int _deviation, int _backstep, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( + _indi, _symbol, _tf, + Util::MakeKey("Indi_ZigZagColor_ON_" + _indi.GetFullName(), _depth, _deviation, _backstep)); + return iZigZagColorOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _depth, _deviation, _backstep, _mode, _shift, + _cache); + } + /** * OnCalculate() method for ZigZag Color indicator. */ diff --git a/Storage/ValueStorage.h b/Storage/ValueStorage.h index 6fa64909a..0348eb0c5 100644 --- a/Storage/ValueStorage.h +++ b/Storage/ValueStorage.h @@ -91,6 +91,17 @@ enum ENUM_IPEAK { IPEAK_LOWEST, IPEAK_HIGHEST }; ValueStorage *_price = INDI.GetValueStorage(APPLIED_PRICE); \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) +#define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(INDI, SYMBOL, TF, KEY) \ + ValueStorage *_time = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_TIME); \ + ValueStorage *_tick_volume = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_TICK_VOLUME); \ + ValueStorage *_volume = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_VOLUME); \ + ValueStorage *_spread = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_SPREAD); \ + ValueStorage *_price_open = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); \ + ValueStorage *_price_high = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); \ + ValueStorage *_price_low = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); \ + ValueStorage *_price_close = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); \ + INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) + #define INDICATOR_CALCULATE_POPULATED_PARAMS_LONG \ _time, _price_open, _price_high, _price_low, _price_close, _tick_volume, _volume, _spread From a94b5c4092a93e3e24a4e3e1ee193aaad1831289 Mon Sep 17 00:00:00 2001 From: kenorb Date: Wed, 8 Dec 2021 23:27:00 +0000 Subject: [PATCH 39/81] SymbolInfo: SymbolInfoEntry: Fixes struct copy constructor --- SymbolInfo.struct.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index e6c1cb1e7..777e7a1f3 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -55,7 +55,8 @@ struct SymbolInfoEntry volume = _tick.volume; spread = (unsigned int)round((ask - bid) * pow(10, SymbolInfoStatic::SymbolInfoInteger(_symbol, SYMBOL_DIGITS))); } - SymbolInfoEntry(const SymbolInfoEntry& _sie) {} + // Copy constructor. + SymbolInfoEntry(const SymbolInfoEntry& _sie) { this = _sie; } // Getters string ToCSV() { return StringFormat("%g,%g,%g,%g,%d", bid, ask, last, spread, volume); } // Serializers. From a493f36b41fde813afa3ca534fc4f98908ff746a Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 9 Dec 2021 19:43:19 +0100 Subject: [PATCH 40/81] WIP. Finished i*OnIndicator mode for all indicators except MA. Changed default shift for IndicatorBase::GetEntry() from -1 to 0. AMA and BWMFI don't work yet. --- Chart.mqh | 2 +- EA.mqh | 2 +- Indicator.define.h | 14 +- Indicator.enum.h | 171 ++++++++++---------- Indicator.mqh | 134 +-------------- Indicator/IndicatorCandle.h | 12 +- Indicator/IndicatorTick.h | 2 +- Indicator/tests/classes/IndicatorTickReal.h | 3 + IndicatorBase.h | 136 +++++++++++++++- Indicators/Bitwise/Indi_Candle.mqh | 2 +- Indicators/Bitwise/Indi_Pattern.mqh | 4 +- Indicators/Indi_AC.mqh | 2 +- Indicators/Indi_AD.mqh | 2 +- Indicators/Indi_ADX.mqh | 2 +- Indicators/Indi_ADXW.mqh | 6 +- Indicators/Indi_AMA.mqh | 55 ++++--- Indicators/Indi_AO.mqh | 2 +- Indicators/Indi_ASI.mqh | 7 +- Indicators/Indi_ATR.mqh | 2 +- Indicators/Indi_Alligator.mqh | 2 +- Indicators/Indi_AppliedPrice.mqh | 2 +- Indicators/Indi_BWMFI.mqh | 4 +- Indicators/Indi_BWZT.mqh | 17 +- Indicators/Indi_Bands.mqh | 2 +- Indicators/Indi_BearsPower.mqh | 2 +- Indicators/Indi_BullsPower.mqh | 2 +- Indicators/Indi_CCI.mqh | 2 +- Indicators/Indi_CHO.mqh | 6 +- Indicators/Indi_CHV.mqh | 6 +- Indicators/Indi_ColorBars.mqh | 5 +- Indicators/Indi_ColorCandlesDaily.mqh | 6 +- Indicators/Indi_ColorLine.mqh | 5 +- Indicators/Indi_CustomMovingAverage.mqh | 4 +- Indicators/Indi_DEMA.mqh | 10 +- Indicators/Indi_DeMarker.mqh | 2 +- Indicators/Indi_Demo.mqh | 2 +- Indicators/Indi_DetrendedPrice.mqh | 6 +- Indicators/Indi_Drawer.mqh | 2 +- Indicators/Indi_Envelopes.mqh | 4 +- Indicators/Indi_Force.mqh | 2 +- Indicators/Indi_FractalAdaptiveMA.mqh | 6 +- Indicators/Indi_Fractals.mqh | 4 +- Indicators/Indi_Gator.mqh | 4 +- Indicators/Indi_HeikenAshi.mqh | 6 +- Indicators/Indi_Ichimoku.mqh | 4 +- Indicators/Indi_Killzones.mqh | 2 +- Indicators/Indi_MA.mqh | 2 +- Indicators/Indi_MACD.mqh | 2 +- Indicators/Indi_MFI.mqh | 2 +- Indicators/Indi_MassIndex.mqh | 6 +- Indicators/Indi_Momentum.mqh | 2 +- Indicators/Indi_OBV.mqh | 2 +- Indicators/Indi_OsMA.mqh | 2 +- Indicators/Indi_Pivot.mqh | 4 +- Indicators/Indi_PriceChannel.mqh | 6 +- Indicators/Indi_PriceFeeder.mqh | 2 +- Indicators/Indi_PriceVolumeTrend.mqh | 6 +- Indicators/Indi_RS.mqh | 2 +- Indicators/Indi_RSI.mqh | 2 +- Indicators/Indi_RVI.mqh | 2 +- Indicators/Indi_RateOfChange.mqh | 6 +- Indicators/Indi_SAR.mqh | 2 +- Indicators/Indi_StdDev.mqh | 2 +- Indicators/Indi_Stochastic.mqh | 2 +- Indicators/Indi_TEMA.mqh | 12 +- Indicators/Indi_TRIX.mqh | 6 +- Indicators/Indi_UltimateOscillator.mqh | 31 +++- Indicators/Indi_VIDYA.mqh | 7 +- Indicators/Indi_VROC.mqh | 6 +- Indicators/Indi_Volumes.mqh | 6 +- Indicators/Indi_WPR.mqh | 2 +- Indicators/Indi_WilliamsAD.mqh | 5 +- Indicators/Indi_ZigZag.mqh | 13 +- Indicators/Indi_ZigZagColor.mqh | 11 +- Indicators/OHLC/Indi_OHLC.mqh | 2 +- Indicators/Price/Indi_Price.mqh | 2 +- Indicators/Special/Indi_Math.mqh | 2 +- Indicators/Tick/Indi_TickMt.mqh | 2 +- tests/IndicatorsTest.mq5 | 5 + 79 files changed, 493 insertions(+), 352 deletions(-) diff --git a/Chart.mqh b/Chart.mqh index a568d8ae5..c73720415 100644 --- a/Chart.mqh +++ b/Chart.mqh @@ -224,7 +224,7 @@ class Chart : public Market { * @return * Returns ChartEntry struct. */ - ChartEntry GetEntry(unsigned int _shift = 0) { + ChartEntry GetEntry(int _shift = 0) { ChartEntry _chart_entry; BarOHLC _ohlc = GetOHLC(_shift); if (_ohlc.open > 0) { diff --git a/EA.mqh b/EA.mqh index 62cd02cb8..cf5ef44d2 100644 --- a/EA.mqh +++ b/EA.mqh @@ -149,7 +149,7 @@ class EA { * @return * Returns TradeSignalEntry struct. */ - TradeSignalEntry GetStrategySignalEntry(Strategy *_strat, bool _trade_allowed = true, int _shift = -1) { + TradeSignalEntry GetStrategySignalEntry(Strategy *_strat, bool _trade_allowed = true, int _shift = 0) { // float _bf = 1.0; float _scl = _strat.Get(STRAT_PARAM_SCL); float _sol = _strat.Get(STRAT_PARAM_SOL); diff --git a/Indicator.define.h b/Indicator.define.h index 6743cba67..ab51a433d 100644 --- a/Indicator.define.h +++ b/Indicator.define.h @@ -43,12 +43,14 @@ } \ SET_HANDLE; \ } \ - int _bars_calc = ::BarsCalculated(_handle); \ - if (GetLastError() > 0) { \ - return EMPTY_VALUE; \ - } else if (_bars_calc <= 2) { \ - SetUserError(ERR_USER_INVALID_BUFF_NUM); \ - return EMPTY_VALUE; \ + if (Terminal::IsVisualMode()) { \ + int _bars_calc = ::BarsCalculated(_handle); \ + if (GetLastError() > 0) { \ + return EMPTY_VALUE; \ + } else if (_bars_calc <= 2) { \ + SetUserError(ERR_USER_INVALID_BUFF_NUM); \ + return EMPTY_VALUE; \ + } \ } \ if (::CopyBuffer(_handle, _mode, _shift, 1, _res) < 0) { \ return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; \ diff --git a/Indicator.enum.h b/Indicator.enum.h index e67e3ff88..c98f42ce1 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -42,90 +42,93 @@ enum ENUM_INDICATOR_ACTION { /* Define type of indicators. */ enum ENUM_INDICATOR_TYPE { - INDI_NONE = 0, // (None) - INDI_AC, // Accelerator Oscillator - INDI_AD, // Accumulation/Distribution - INDI_ADX, // Average Directional Index - INDI_ADXW, // ADX by Welles Wilder - INDI_ALLIGATOR, // Alligator - INDI_AMA, // Adaptive Moving Average - INDI_APPLIED_PRICE, // Applied Price over OHLC Indicator - INDI_AO, // Awesome Oscillator - INDI_ASI, // Accumulation Swing Index - INDI_ATR, // Average True Range - INDI_BANDS, // Bollinger Bands - INDI_BANDS_ON_PRICE, // Bollinger Bands (on Price) - INDI_BEARS, // Bears Power - INDI_BULLS, // Bulls Power - INDI_BWMFI, // Market Facilitation Index - INDI_BWZT, // Bill Williams' Zone Trade - INDI_CANDLE, // Candle Pattern Detector - INDI_CCI, // Commodity Channel Index - INDI_CCI_ON_PRICE, // Commodity Channel Index (CCI) (on Price) - INDI_CHAIKIN, // Chaikin Oscillator - INDI_CHAIKIN_V, // Chaikin Volatility - INDI_COLOR_BARS, // Color Bars - INDI_COLOR_CANDLES_DAILY, // Color Candles Daily - INDI_COLOR_LINE, // Color Line - INDI_CUSTOM, // Custom indicator - INDI_CUSTOM_MOVING_AVG, // Custom Moving Average - INDI_DEMA, // Double Exponential Moving Average - INDI_DEMARKER, // DeMarker - INDI_DEMO, // Demo/Dummy Indicator - INDI_DETRENDED_PRICE, // Detrended Price Oscillator - INDI_DRAWER, // Drawer (Socket-based) Indicator - INDI_ENVELOPES, // Envelopes - INDI_ENVELOPES_ON_PRICE, // Evelopes (on Price) - INDI_FORCE, // Force Index - INDI_FRACTALS, // Fractals - INDI_FRAMA, // Fractal Adaptive Moving Average - INDI_GATOR, // Gator Oscillator - INDI_HEIKENASHI, // Heiken Ashi - INDI_ICHIMOKU, // Ichimoku Kinko Hyo - INDI_KILLZONES, // Killzones - INDI_MA, // Moving Average - INDI_MACD, // MACD - INDI_MA_ON_PRICE, // Moving Average (on Price). - INDI_MARKET_FI, // Market Facilitation Index - INDI_MASS_INDEX, // Mass Index - INDI_MFI, // Money Flow Index - INDI_MOMENTUM, // Momentum - INDI_MOMENTUM_ON_PRICE, // Momentum (on Price) - INDI_OBV, // On Balance Volume - INDI_OHLC, // OHLC (Open-High-Low-Close) - INDI_OSMA, // OsMA - INDI_PATTERN, // Pattern Detector - INDI_PIVOT, // Pivot Detector - INDI_PRICE, // Price - INDI_PRICE_CHANNEL, // Price Channel - INDI_PRICE_FEEDER, // Indicator which returns prices from custom array - INDI_PRICE_VOLUME_TREND, // Price and Volume Trend - INDI_RATE_OF_CHANGE, // Rate of Change - INDI_RS, // Indi_Math-based RSI indicator. - INDI_RSI, // Relative Strength Index - INDI_RSI_ON_PRICE, // Relative Strength Index (RSI) (on Price) - INDI_RVI, // Relative Vigor Index - INDI_SAR, // Parabolic SAR - INDI_SPECIAL_MATH, // Math operations over given indicator. - INDI_STDDEV, // Standard Deviation - INDI_STDDEV_ON_MA_SMA, // Standard Deviation on Moving Average in SMA mode - INDI_STDDEV_ON_PRICE, // Standard Deviation (on Price) - INDI_STDDEV_SMA_ON_PRICE, // Standard Deviation in SMA mode (on Price) - INDI_STOCHASTIC, // Stochastic Oscillator - INDI_SVE_BB, // SVE Bollinger Bands - INDI_TEMA, // Triple Exponential Moving Average - INDI_TF, // Timeframe - INDI_TICK, // Tick - INDI_TMA_TRUE, // Triangular Moving Average True - INDI_TRIX, // Triple Exponential Moving Averages Oscillator - INDI_ULTIMATE_OSCILLATOR, // Ultimate Oscillator - INDI_VIDYA, // Variable Index Dynamic Average - INDI_VOLUMES, // Volumes - INDI_VROC, // Volume Rate of Change - INDI_WILLIAMS_AD, // Larry Williams' Accumulation/Distribution - INDI_WPR, // Williams' Percent Range - INDI_ZIGZAG, // ZigZag - INDI_ZIGZAG_COLOR, // ZigZag Color + INDI_NONE = 0, // (None) + INDI_AC, // Accelerator Oscillator + INDI_AD, // Accumulation/Distribution + INDI_ADX, // Average Directional Index + INDI_ADXW, // ADX by Welles Wilder + INDI_ALLIGATOR, // Alligator + INDI_AMA, // Adaptive Moving Average + INDI_APPLIED_PRICE, // Applied Price over OHLC Indicator + INDI_AO, // Awesome Oscillator + INDI_ASI, // Accumulation Swing Index + INDI_ATR, // Average True Range + INDI_BANDS, // Bollinger Bands + INDI_BANDS_ON_PRICE, // Bollinger Bands (on Price) + INDI_BEARS, // Bears Power + INDI_BULLS, // Bulls Power + INDI_BWMFI, // Market Facilitation Index + INDI_BWZT, // Bill Williams' Zone Trade + INDI_CANDLE, // Candle Pattern Detector + INDI_CCI, // Commodity Channel Index + INDI_CCI_ON_PRICE, // Commodity Channel Index (CCI) (on Price) + INDI_CHAIKIN, // Chaikin Oscillator + INDI_CHAIKIN_V, // Chaikin Volatility + INDI_COLOR_BARS, // Color Bars + INDI_COLOR_CANDLES_DAILY, // Color Candles Daily + INDI_COLOR_LINE, // Color Line + INDI_CUSTOM, // Custom indicator + INDI_CUSTOM_MOVING_AVG, // Custom Moving Average + INDI_DEMA, // Double Exponential Moving Average + INDI_DEMARKER, // DeMarker + INDI_DEMO, // Demo/Dummy Indicator + INDI_DETRENDED_PRICE, // Detrended Price Oscillator + INDI_DRAWER, // Drawer (Socket-based) Indicator + INDI_ENVELOPES, // Envelopes + INDI_ENVELOPES_ON_PRICE, // Evelopes (on Price) + INDI_FORCE, // Force Index + INDI_FRACTALS, // Fractals + INDI_FRAMA, // Fractal Adaptive Moving Average + INDI_GATOR, // Gator Oscillator + INDI_HEIKENASHI, // Heiken Ashi + INDI_ICHIMOKU, // Ichimoku Kinko Hyo + INDI_KILLZONES, // Killzones + INDI_MA, // Moving Average + INDI_MACD, // MACD + INDI_MA_ON_PRICE, // Moving Average (on Price). + INDI_MARKET_FI, // Market Facilitation Index + INDI_MASS_INDEX, // Mass Index + INDI_MFI, // Money Flow Index + INDI_MOMENTUM, // Momentum + INDI_MOMENTUM_ON_PRICE, // Momentum (on Price) + INDI_OBV, // On Balance Volume + INDI_OHLC, // OHLC (Open-High-Low-Close) + INDI_OSMA, // OsMA + INDI_PATTERN, // Pattern Detector + INDI_PIVOT, // Pivot Detector + INDI_PRICE, // Price + INDI_PRICE_CHANNEL, // Price Channel + INDI_PRICE_FEEDER, // Indicator which returns prices from custom array + INDI_PRICE_VOLUME_TREND, // Price and Volume Trend + INDI_RATE_OF_CHANGE, // Rate of Change + INDI_RS, // Indi_Math-based RSI indicator. + INDI_RSI, // Relative Strength Index + INDI_RSI_ON_PRICE, // Relative Strength Index (RSI) (on Price) + INDI_RVI, // Relative Vigor Index + INDI_SAR, // Parabolic SAR + INDI_SPECIAL_MATH, // Math operations over given indicator. + INDI_STDDEV, // Standard Deviation + INDI_STDDEV_ON_MA_SMA, // Standard Deviation on Moving Average in SMA mode + INDI_STDDEV_ON_PRICE, // Standard Deviation (on Price) + INDI_STDDEV_SMA_ON_PRICE, // Standard Deviation in SMA mode (on Price) + INDI_STOCHASTIC, // Stochastic Oscillator + INDI_SVE_BB, // SVE Bollinger Bands + INDI_TEMA, // Triple Exponential Moving Average + INDI_TF, // Timeframe + INDI_TICK, // Tick + INDI_TMA_TRUE, // Triangular Moving Average True + INDI_TRIX, // Triple Exponential Moving Averages Oscillator + INDI_ULTIMATE_OSCILLATOR, // Ultimate Oscillator + INDI_ULTIMATE_OSCILLATOR_ATR_FAST, // Ultimate Oscillator's ATR, Fast + INDI_ULTIMATE_OSCILLATOR_ATR_MIDDLE, // Ultimate Oscillator's ATR, Middle + INDI_ULTIMATE_OSCILLATOR_ATR_SLOW, // Ultimate Oscillator's ATR, Slow + INDI_VIDYA, // Variable Index Dynamic Average + INDI_VOLUMES, // Volumes + INDI_VROC, // Volume Rate of Change + INDI_WILLIAMS_AD, // Larry Williams' Accumulation/Distribution + INDI_WPR, // Williams' Percent Range + INDI_ZIGZAG, // ZigZag + INDI_ZIGZAG_COLOR, // ZigZag Color FINAL_INDICATOR_TYPE_ENTRY }; diff --git a/Indicator.mqh b/Indicator.mqh index 389d9fc54..665ca3060 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -176,7 +176,7 @@ class Indicator : public IndicatorBase { /** * Gets an indicator property flag. */ - bool GetFlag(INDICATOR_ENTRY_FLAGS _prop, int _shift = -1) { + bool GetFlag(INDICATOR_ENTRY_FLAGS _prop, int _shift = 0) { IndicatorDataEntry _entry = GetEntry(_shift >= 0 ? _shift : iparams.GetShift()); return _entry.CheckFlag(_prop); } @@ -1166,138 +1166,6 @@ class Indicator : public IndicatorBase { virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _index = -1) { _entry.AddFlags(_entry.GetDataTypeFlags(iparams.GetDataValueType())); }; - - /* Defines MQL backward compatible methods */ - - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, DUMMY); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, int _mode, int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _b, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a COMMA _b); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, int _mode, - int _shift) { -#ifdef __MQL4__ - return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _mode, _shift); -#else // __MQL5__ - ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, int _mode, - int _shift) { -#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); -#endif - } - - template - double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, - int _mode, int _shift) { -#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); -#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, - int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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, int _mode, int _shift) { -#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); -#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 - } }; #endif diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 34dbc37c6..6a36c4312 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -85,7 +85,7 @@ class IndicatorCandle : public IndicatorBase { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - IndicatorDataEntry GetEntry(int _index = -1) override { + IndicatorDataEntry GetEntry(int _index) override { ResetLastError(); unsigned int _ishift = _index >= 0 ? _index : icparams.GetShift(); long _candle_time = CalcCandleTimestamp(GetBarTime(_ishift)); @@ -118,7 +118,7 @@ class IndicatorCandle : public IndicatorBase { * @return * Returns DataParamEntry struct filled with a single value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : icparams.GetShift(); return GetEntry(_ishift)[_mode]; } @@ -205,9 +205,11 @@ class IndicatorCandle : public IndicatorBase { indi_src.Ptr().RemoveListener(THIS_PTR); } indi_src = _indi; - indi_src.Ptr().AddListener(THIS_PTR); - icparams.SetDataSource(-1, _input_mode); - indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); + if (_indi != NULL) { + indi_src.Ptr().AddListener(THIS_PTR); + icparams.SetDataSource(-1, _input_mode); + indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); + } } string CandlesToString() { diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 4cf53be6b..79784d472 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -145,7 +145,7 @@ class IndicatorTick : public IndicatorBase { * @return * Returns DataParamEntry struct filled with a single value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : itparams.GetShift(); return GetEntry(_ishift)[_mode]; } diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index 668ddc1bf..a8884c3a6 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -74,6 +74,9 @@ class IndicatorTickReal : public IndicatorTick } } + // Clearing possible error 4004. + ResetLastError(); + for (int i = 0; i < _num_copied; ++i) { TickAB _tick(_ticks[i].ask, _ticks[i].bid); // We can't call EmitEntry() here, as tick would go to multiple sources at the same time! diff --git a/IndicatorBase.h b/IndicatorBase.h index a0bed2b73..5d74af976 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -507,7 +507,7 @@ class IndicatorBase : public Chart { /** * Returns the indicator's struct value. */ - virtual IndicatorDataEntry GetEntry(int _index = -1) = NULL; + virtual IndicatorDataEntry GetEntry(int _index = 0) = NULL; /** * Alters indicator's struct value. @@ -553,7 +553,7 @@ class IndicatorBase : public Chart { /** * Returns indicator value for a given shift and mode. */ - // virtual double GetValue(int _shift = -1, int _mode = 0) = NULL; + // virtual double GetValue(int _shift = 0, int _mode = 0) = NULL; /** * Checks whether indicator has a valid value for a given shift. @@ -635,6 +635,138 @@ class IndicatorBase : public Chart { * 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) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, DUMMY); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, int _mode, int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _b, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a COMMA _b); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, int _mode, + int _shift) { +#ifdef __MQL4__ + return ::iCustom(_symbol, _tf, _name, _a, _b, _c, _mode, _shift); +#else // __MQL5__ + ICUSTOM_DEF(;, COMMA _a COMMA _b COMMA _c); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, int _mode, + int _shift) { +#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); +#endif + } + + template + double iCustom(int& _handle, string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C _c, D _d, E _e, + int _mode, int _shift) { +#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); +#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, + int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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, int _mode, int _shift) { +#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); +#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/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index a9b94aea1..40575e792 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -66,7 +66,7 @@ class Indi_Candle : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); BarOHLC _ohlcs[1]; diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index f9e014ec0..fec403314 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -57,7 +57,7 @@ class Indi_Pattern : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int i; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); BarOHLC _ohlcs[8]; @@ -112,7 +112,7 @@ class Indi_Pattern : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _shift = 0) { _entry.SetFlag(INDI_ENTRY_FLAG_IS_BITWISE, true); Indicator::GetEntryAlter(_entry); } diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index be9fe709b..8c222b537 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -100,7 +100,7 @@ class Indi_AC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { IndicatorDataEntryValue _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index 51ea677cf..8473fe8de 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -101,7 +101,7 @@ class Indi_AD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 752805800..041d8b975 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -115,7 +115,7 @@ class Indi_ADX : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index b8142fd78..bac89a6c8 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -225,7 +225,7 @@ class Indi_ADXW : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -237,6 +237,10 @@ class Indi_ADXW : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_ADXW::iADXWilderOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod() /*]*/, _mode, + _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index d71d33756..4342dad6c 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -22,13 +22,14 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTf.h" +#include "../Indicator/tests/classes/IndicatorTickReal.h" #include "../Storage/ValueStorage.h" #include "../Storage/ValueStorage.price.h" #include "Price/Indi_Price.mqh" // Structs. -struct IndiAMAParams : IndicatorParams { +struct IndiAMAParams : IndicatorTfParams { unsigned int period; unsigned int fast_period; unsigned int slow_period; @@ -41,8 +42,7 @@ struct IndiAMAParams : IndicatorParams { fast_period(_fast_period), slow_period(_slow_period), ama_shift(_ama_shift), - applied_price(_ap), - IndicatorParams(INDI_AMA, 1, TYPE_DOUBLE) { + applied_price(_ap) { SetDataValueRange(IDATA_RANGE_PRICE); SetShift(_shift); switch (idstype) { @@ -62,13 +62,26 @@ struct IndiAMAParams : IndicatorParams { /** * Implements the AMA indicator. */ -class Indi_AMA : public Indicator { +class Indi_AMA : public IndicatorTf { public: /** * Class constructor. */ - 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){}; + Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTf(_p) { + icparams.SetIndicatorType(INDI_AMA); + if (_indi_src != NULL) { + SetDataSource(_indi_src); + icparams.SetDataSourceType(IDATA_INDICATOR); + } else { + // Defaulting to platform ticks. + SetDataSource(new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal")); + icparams.SetDataSourceType(IDATA_INDICATOR); + } + }; + Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTf(_tf) { + icparams.SetIndicatorType(INDI_AMA); + icparams.SetShift(_shift); + }; /** * Built-in version of AMA. @@ -213,16 +226,16 @@ class Indi_AMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; - int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + int _ishift = _shift >= 0 ? _shift : icparams.GetShift(); + switch (icparams.idstype) { case IDATA_BUILTIN: _value = Indi_AMA::iAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), + _value = iCustom(istate.handle, GetSymbol(), GetTf(), icparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), GetAMAShift() /*]*/, _mode, _ishift); break; @@ -242,27 +255,27 @@ class Indi_AMA : public Indicator { /** * Get AMA shift. */ - unsigned int GetAMAShift() { return iparams.ama_shift; } + unsigned int GetAMAShift() { return icparams.ama_shift; } /** * Get period. */ - unsigned int GetPeriod() { return iparams.period; } + unsigned int GetPeriod() { return icparams.period; } /** * Get fast period. */ - unsigned int GetFastPeriod() { return iparams.fast_period; } + unsigned int GetFastPeriod() { return icparams.fast_period; } /** * Get slow period. */ - unsigned int GetSlowPeriod() { return iparams.slow_period; } + unsigned int GetSlowPeriod() { return icparams.slow_period; } /** * Get applied price. */ - ENUM_APPLIED_PRICE GetAppliedPrice() { return iparams.applied_price; } + ENUM_APPLIED_PRICE GetAppliedPrice() { return icparams.applied_price; } /* Setters */ @@ -271,7 +284,7 @@ class Indi_AMA : public Indicator { */ void SetAMAShift(unsigned int _ama_shift) { istate.is_changed = true; - iparams.ama_shift = _ama_shift; + icparams.ama_shift = _ama_shift; } /** @@ -279,7 +292,7 @@ class Indi_AMA : public Indicator { */ void SetPeriod(unsigned int _period) { istate.is_changed = true; - iparams.period = _period; + icparams.period = _period; } /** @@ -287,7 +300,7 @@ class Indi_AMA : public Indicator { */ void SetFastPeriod(unsigned int _fast_period) { istate.is_changed = true; - iparams.fast_period = _fast_period; + icparams.fast_period = _fast_period; } /** @@ -295,7 +308,7 @@ class Indi_AMA : public Indicator { */ void SetSlowPeriod(unsigned int _slow_period) { istate.is_changed = true; - iparams.slow_period = _slow_period; + icparams.slow_period = _slow_period; } /** @@ -303,6 +316,6 @@ class Indi_AMA : public Indicator { */ void SetAppliedPrice(ENUM_APPLIED_PRICE _applied_price) { istate.is_changed = true; - iparams.applied_price = _applied_price; + icparams.applied_price = _applied_price; } }; diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index a88552202..e65e367aa 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -103,7 +103,7 @@ class Indi_AO : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 1e9f54281..1f18b15a5 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -165,7 +165,7 @@ class Indi_ASI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -178,8 +178,11 @@ class Indi_ASI : public Indicator { Util::MakeKey("Indi_ASI", GetMaximumPriceChanging())); _value = iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, GetMaximumPriceChanging(), _mode, _ishift, _cache); + } break; + case IDATA_INDICATOR: + _value = Indi_ASI::iASIOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetMaximumPriceChanging() /*]*/, + _mode, _ishift, THIS_PTR); break; - } default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index c74f1edd6..f0d65d2f1 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -103,7 +103,7 @@ class Indi_ATR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index 62b552df7..52acbfd76 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -162,7 +162,7 @@ class Indi_Alligator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); #ifdef __MQL4__ diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index 379596331..90e78ed63 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -74,7 +74,7 @@ class Indi_AppliedPrice : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index cc8b55e08..b0e3e1853 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -114,7 +114,7 @@ class Indi_BWMFI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = BWMFI_BUFFER, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = BWMFI_BUFFER, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -136,7 +136,7 @@ class Indi_BWMFI : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { Indicator::GetEntryAlter(_entry); #ifdef __MQL4__ // @see: https://en.wikipedia.org/wiki/Market_facilitation_index diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 08405e14f..73d027824 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -40,8 +40,8 @@ enum ENUM_INDI_BWZT_MODE { // Structs. struct IndiBWZTParams : IndicatorParams { - Indi_AC *indi_ac; - Indi_AC *indi_ao; + Ref indi_ac; + Ref indi_ao; unsigned int period; unsigned int second_period; unsigned int sum_period; @@ -109,8 +109,8 @@ class Indi_BWZT : public Indicator { /** * On-indicator version of BWZT. */ - static double iBWZTOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode, - int _shift, IndicatorBase *_obj) { + static double iBWZTOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode, int _shift, + IndicatorBase *_obj) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_BWZT_ON_" + _indi.GetFullName())); @@ -126,9 +126,9 @@ class Indi_BWZT : public Indicator { virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { switch (_id) { case INDI_AC: - return iparams.indi_ac; + return iparams.indi_ac.Ptr(); case INDI_AO: - return iparams.indi_ac; + return iparams.indi_ac.Ptr(); } return NULL; @@ -204,7 +204,7 @@ class Indi_BWZT : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -214,6 +214,9 @@ class Indi_BWZT : public Indicator { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_BWZT::iBWZTOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); break; diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index 0ff6a92e1..a368d6b85 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -239,7 +239,7 @@ class Indi_Bands : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = BAND_BASE, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = BAND_BASE, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index 1b9721606..b2bb83164 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -104,7 +104,7 @@ class Indi_BearsPower : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index 1741f8da7..1e55f0010 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -104,7 +104,7 @@ class Indi_BullsPower : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index c32d4c191..ed4f71c4a 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -145,7 +145,7 @@ class Indi_CCI : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; switch (iparams.idstype) { diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index 6106dbefe..a42f126a7 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -180,7 +180,7 @@ class Indi_CHO : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -192,6 +192,10 @@ class Indi_CHO : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetFastMA(), GetSlowMA(), GetSmoothMethod(), GetInputVolume() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_CHO::iChaikinOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetFastMA(), GetSlowMA(), + GetSmoothMethod(), GetInputVolume() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 8b8f9490e..1c0c15119 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -175,7 +175,7 @@ class Indi_CHV : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -187,6 +187,10 @@ class Indi_CHV : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetSmoothPeriod(), GetCHVPeriod(), GetSmoothMethod() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_CHV::iCHVOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetSmoothPeriod(), + GetCHVPeriod(), GetSmoothMethod() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index 676a91767..ae5dfcd9e 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -123,7 +123,7 @@ class Indi_ColorBars : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -133,6 +133,9 @@ class Indi_ColorBars : public Indicator { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_ColorBars::iColorBarsOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); break; diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 1515cdc45..140320f7b 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -120,7 +120,7 @@ class Indi_ColorCandlesDaily : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -130,6 +130,10 @@ class Indi_ColorCandlesDaily : public Indicator { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; + case IDATA_INDICATOR: + _value = + Indi_ColorCandlesDaily::iCCDOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_ColorLine.mqh b/Indicators/Indi_ColorLine.mqh index 886c70737..fcf734106 100644 --- a/Indicators/Indi_ColorLine.mqh +++ b/Indicators/Indi_ColorLine.mqh @@ -198,7 +198,7 @@ class Indi_ColorLine : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -208,6 +208,9 @@ class Indi_ColorLine : public Indicator { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_ColorLine::iColorLineOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index 7d83ee7dc..664251971 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -32,7 +32,7 @@ struct IndiCustomMovingAverageParams : IndicatorParams { // Struct constructor. IndiCustomMovingAverageParams(int _smooth_period = 13, int _smooth_shift = 0, ENUM_MA_METHOD _smooth_method = MODE_SMMA, int _shift = 0) - : IndicatorParams(INDI_CUSTOM_MOVING_AVG, 3, TYPE_DOUBLE) { + : IndicatorParams(INDI_CUSTOM_MOVING_AVG, 1, TYPE_DOUBLE) { SetDataValueRange(IDATA_RANGE_MIXED); SetDataSourceType(IDATA_ICUSTOM); #ifdef __MQL5__ @@ -67,7 +67,7 @@ class Indi_CustomMovingAverage : public Indicator /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index e89f07723..4621be7c2 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -176,7 +176,7 @@ class Indi_DEMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); @@ -185,8 +185,8 @@ class Indi_DEMA : public Indicator { // We're getting DEMA from Price indicator. istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_DEMA::iDEMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetAppliedPrice(), _ishift, _mode, - THIS_PTR); + _value = Indi_DEMA::iDEMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetMAShift(), GetAppliedPrice() /*]*/, + _ishift, _mode, THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; @@ -195,8 +195,8 @@ class Indi_DEMA : public Indicator { break; case IDATA_INDICATOR: // Calculating DEMA value from specified indicator. - _value = Indi_DEMA::iDEMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), - GetAppliedPrice(), _mode, _ishift, THIS_PTR); + _value = Indi_DEMA::iDEMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetMAShift(), + GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); break; } return _value; diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index 98524dcdb..cea440264 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -102,7 +102,7 @@ class Indi_DeMarker : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index a5bf323d5..cdf8fbb2e 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -72,7 +72,7 @@ class Indi_Demo : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = Indi_Demo::iDemo(GetSymbol(), GetTf(), _ishift, THIS_PTR); if (iparams.is_draw) { diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index ef34a7391..9c60f2207 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -126,7 +126,7 @@ class Indi_DetrendedPrice : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -138,6 +138,10 @@ class Indi_DetrendedPrice : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_DetrendedPrice::iDPOOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_Drawer.mqh b/Indicators/Indi_Drawer.mqh index 2fc3c2593..3130ea7c6 100644 --- a/Indicators/Indi_Drawer.mqh +++ b/Indicators/Indi_Drawer.mqh @@ -172,7 +172,7 @@ class Indi_Drawer : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index 4761ab8ce..bc4e5c41a 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -197,7 +197,7 @@ class Indi_Envelopes : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -225,7 +225,7 @@ class Indi_Envelopes : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { Indicator::GetEntryAlter(_entry); #ifdef __MQL4__ // The LINE_MAIN only exists in MQL4 for Envelopes. diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 9e047338b..a752c8938 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -117,7 +117,7 @@ class Indi_Force : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 67dc21173..63b2b1246 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -145,7 +145,7 @@ class Indi_FrAMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -157,6 +157,10 @@ class Indi_FrAMA : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetFRAMAShift() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_FrAMA::iFrAMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetFRAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 49d395311..832f5d9aa 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -102,7 +102,7 @@ class Indi_Fractals : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -122,7 +122,7 @@ class Indi_Fractals : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { Indicator::GetEntryAlter(_entry); #ifdef __MQL4__ // In MT4 line identifiers starts from 1, so populating also at 0. diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index 9dca4b882..e256b21b7 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -169,7 +169,7 @@ class Indi_Gator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -196,7 +196,7 @@ class Indi_Gator : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { Indicator::GetEntryAlter(_entry); #ifdef __MQL4__ // @todo: Can we calculate upper and lower histogram color in MT4? diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 5239c1790..52c15667e 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -205,7 +205,7 @@ class Indi_HeikenAshi : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = HA_OPEN, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = HA_OPEN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -237,6 +237,10 @@ class Indi_HeikenAshi : public Indicator { _value = Indi_HeikenAshi::iCustomLegacyHeikenAshi(GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), _mode, _ishift, THIS_PTR); break; + case IDATA_INDICATOR: + _value = + Indi_HeikenAshi::iHeikenAshiOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 0f381d8d5..2b3378c79 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -142,7 +142,7 @@ class Indi_Ichimoku : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -164,7 +164,7 @@ class Indi_Ichimoku : public Indicator { /** * Alters indicator's struct value. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { Indicator::GetEntryAlter(_entry); #ifdef __MQL4__ // In MQL4 value of LINE_TENKANSEN is 1 (not 0 as in MQL5), diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index 70016b6db..89913eeb5 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -106,7 +106,7 @@ class Indi_Killzones : public Indicator { /** * Returns the indicator's value. */ - IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { float _value = FLT_MAX; int _index = (int)_mode / 2; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index d8ec96e68..3cdd2083d 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -627,7 +627,7 @@ class Indi_MA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index 64570f79b..6724dfc2a 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -114,7 +114,7 @@ class Indi_MACD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 902d6d08b..4a9327585 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -111,7 +111,7 @@ class Indi_MFI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 1e0076f55..3b4821127 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -166,7 +166,7 @@ class Indi_MassIndex : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -178,6 +178,10 @@ class Indi_MassIndex : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetSecondPeriod(), GetSumPeriod() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_MassIndex::iMIOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetSecondPeriod(), GetSumPeriod() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); break; diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 5f4266dd0..0d461e47c 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -141,7 +141,7 @@ class Indi_Momentum : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index cefa485e9..b904b3e52 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -118,7 +118,7 @@ class Indi_OBV : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index ac0a608a7..a6930aab8 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -111,7 +111,7 @@ class Indi_OsMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; switch (iparams.idstype) { diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index fd4c7cf4d..6ef493d08 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -62,7 +62,7 @@ class Indi_Pivot : public Indicator { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - virtual IndicatorDataEntry GetEntry(int _shift = -1) { + virtual IndicatorDataEntry GetEntry(int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); long _bar_time = GetBarTime(_ishift); IndicatorDataEntry _entry = idata.GetByKey(_bar_time); @@ -100,7 +100,7 @@ class Indi_Pivot : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); return GetEntry(_ishift)[_mode]; } diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index 415082498..afcc17ed5 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -116,7 +116,7 @@ class Indi_PriceChannel : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -127,6 +127,10 @@ class Indi_PriceChannel : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_PriceChannel::iPriceChannelOnIndicator(GetDataSource(), GetSymbol(), GetTf(), + /*[*/ GetPeriod() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_PriceFeeder.mqh b/Indicators/Indi_PriceFeeder.mqh index c1d286d88..459c8e8df 100644 --- a/Indicators/Indi_PriceFeeder.mqh +++ b/Indicators/Indi_PriceFeeder.mqh @@ -75,7 +75,7 @@ class Indi_PriceFeeder : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int data_size = ArraySize(iparams.price_data); int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); diff --git a/Indicators/Indi_PriceVolumeTrend.mqh b/Indicators/Indi_PriceVolumeTrend.mqh index ecf0ae493..35b40cdc9 100644 --- a/Indicators/Indi_PriceVolumeTrend.mqh +++ b/Indicators/Indi_PriceVolumeTrend.mqh @@ -131,7 +131,7 @@ class Indi_PriceVolumeTrend : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -143,6 +143,10 @@ class Indi_PriceVolumeTrend : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetAppliedVolume() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_PriceVolumeTrend::iPVTOnIndicator(GetDataSource(), GetSymbol(), GetTf(), + /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_RS.mqh b/Indicators/Indi_RS.mqh index 51c03ed8d..29df1fecb 100644 --- a/Indicators/Indi_RS.mqh +++ b/Indicators/Indi_RS.mqh @@ -78,7 +78,7 @@ class Indi_RS : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_MATH: diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index 41b7339a9..41af38bbe 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -289,7 +289,7 @@ class Indi_RSI : public Indicator { * Note that in MQL5 Applied Price must be passed as the last parameter * (before mode and shift). */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; double _res[]; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index 18402acad..e7c7d8b39 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -103,7 +103,7 @@ class Indi_RVI : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index fd597bbe0..e6508ddab 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -120,7 +120,7 @@ class Indi_RateOfChange : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -132,6 +132,10 @@ class Indi_RateOfChange : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_RateOfChange::iROCOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_SAR.mqh b/Indicators/Indi_SAR.mqh index 2381c9cf3..bb7acb110 100644 --- a/Indicators/Indi_SAR.mqh +++ b/Indicators/Indi_SAR.mqh @@ -102,7 +102,7 @@ class Indi_SAR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 4ef932b03..4dc2327eb 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -226,7 +226,7 @@ class Indi_StdDev : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index d60246205..95384d8ae 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -119,7 +119,7 @@ class Indi_Stochastic : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 626ad9186..5ac6bbb6c 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -97,9 +97,9 @@ class Indi_TEMA : public Indicator { /** * On-indicator version of TEMA. */ - static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, - int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + static double iTEMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, + IndicatorBase *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_TEMA_ON_" + _indi.GetFullName(), _ma_period, _ma_shift, (int)_ap)); @@ -138,7 +138,7 @@ class Indi_TEMA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -150,6 +150,10 @@ class Indi_TEMA : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetTEMAShift() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_TEMA::iTEMAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetTEMAShift(), + GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); break; diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index da77f4e33..e480701b7 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -137,7 +137,7 @@ class Indi_TRIX : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -149,6 +149,10 @@ class Indi_TRIX : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod() /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_TRIX::iTriXOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index ee6782641..ff63857d4 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -29,6 +29,9 @@ // Structs. struct IndiUltimateOscillatorParams : IndicatorParams { + Ref indi_atr_fast; + Ref indi_atr_middle; + Ref indi_atr_slow; int fast_period; int middle_period; int slow_period; @@ -125,14 +128,29 @@ class Indi_UltimateOscillator : public Indicator { _fast_k, _middle_k, _slow_k)); // @fixit This won't work! Find a way to differentiate ATRs. - Indi_ATR *_indi_atr_fast = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); - Indi_ATR *_indi_atr_middle = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); - Indi_ATR *_indi_atr_slow = (Indi_ATR *)_indi.GetDataSource(INDI_ATR); + Indi_ATR *_indi_atr_fast = (Indi_ATR *)_indi.GetDataSource(INDI_ULTIMATE_OSCILLATOR_ATR_FAST); + Indi_ATR *_indi_atr_middle = (Indi_ATR *)_indi.GetDataSource(INDI_ULTIMATE_OSCILLATOR_ATR_MIDDLE); + Indi_ATR *_indi_atr_slow = (Indi_ATR *)_indi.GetDataSource(INDI_ULTIMATE_OSCILLATOR_ATR_SLOW); return iUOOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _fast_period, _middle_period, _slow_period, _fast_k, _middle_k, _slow_k, _mode, _shift, _cache, _indi_atr_fast, _indi_atr_middle, _indi_atr_slow); } + /** + * Provides built-in indicators whose can be used as data source. + */ + IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { + switch (_id) { + case INDI_ULTIMATE_OSCILLATOR_ATR_FAST: + return iparams.indi_atr_fast.Ptr(); + case INDI_ULTIMATE_OSCILLATOR_ATR_MIDDLE: + return iparams.indi_atr_middle.Ptr(); + case INDI_ULTIMATE_OSCILLATOR_ATR_SLOW: + return iparams.indi_atr_slow.Ptr(); + } + return NULL; + } + /** * OnCalculate() method for Ultimate Oscillator. */ @@ -229,7 +247,7 @@ class Indi_UltimateOscillator : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -245,6 +263,11 @@ class Indi_UltimateOscillator : public Indicator { /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_UltimateOscillator::iUOOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetFastPeriod(), + GetMiddlePeriod(), GetSlowPeriod(), GetFastK(), GetMiddleK(), + GetSlowK() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_VIDYA.mqh b/Indicators/Indi_VIDYA.mqh index 15f959e15..8499e9b32 100644 --- a/Indicators/Indi_VIDYA.mqh +++ b/Indicators/Indi_VIDYA.mqh @@ -160,7 +160,7 @@ class Indi_VIDYA : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -175,6 +175,11 @@ class Indi_VIDYA : public Indicator { /*]*/, 0, _ishift); break; + case IDATA_INDICATOR: + _value = + Indi_VIDYA::iVIDyAOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetCMOPeriod(), GetMAPeriod(), + GetVIDYAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index dfad54d06..439e009fe 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -140,7 +140,7 @@ class Indi_VROC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -152,6 +152,10 @@ class Indi_VROC : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_VROC::iVROCOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetPeriod(), + GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 4fb2a2888..1f5333b93 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -134,7 +134,7 @@ class Indi_Volumes : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -145,6 +145,10 @@ class Indi_Volumes : public Indicator { _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_Volumes::iVolumesOnIndicator(GetDataSource(), GetSymbol(), GetTf(), + /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index 8dcc258aa..1504f2ecf 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -101,7 +101,7 @@ class Indi_WPR : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 36b56685b..cf1a6513f 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -134,7 +134,7 @@ class Indi_WilliamsAD : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -144,6 +144,9 @@ class Indi_WilliamsAD : public Indicator { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), 0, _ishift); break; + case IDATA_INDICATOR: + _value = Indi_WilliamsAD::iWADOnIndicator(GetDataSource(), GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); } diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index e79ca128c..912eb8eff 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -346,18 +346,23 @@ class Indi_ZigZag : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_ZigZag::iZigZag(GetSymbol(), GetTf(), GetDepth(), GetDeviation(), GetBackstep(), + _value = Indi_ZigZag::iZigZag(GetSymbol(), GetTf(), /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; - _value = Indi_ZigZag::iCustomZigZag(GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), GetDepth(), - GetDeviation(), GetBackstep(), (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); + _value = + Indi_ZigZag::iCustomZigZag(GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetDepth(), + GetDeviation(), GetBackstep() /*]*/, (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); + break; + case IDATA_INDICATOR: + _value = Indi_ZigZag::iZigZagOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetDepth(), + GetDeviation(), GetBackstep() /*]*/, _mode, _ishift, THIS_PTR); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index f30004ebb..af74e2f50 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -281,18 +281,23 @@ class Indi_ZigZagColor : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { case IDATA_BUILTIN: - _value = Indi_ZigZagColor::iZigZagColor(GetSymbol(), GetTf(), GetDepth(), GetDeviation(), GetBackstep(), - (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); + _value = Indi_ZigZagColor::iZigZagColor(GetSymbol(), GetTf(), /*[*/ GetDepth(), GetDeviation(), + GetBackstep() /*]*/, (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, _mode, _ishift); break; + case IDATA_INDICATOR: + _value = + Indi_ZigZagColor::iZigZagColorOnIndicator(GetDataSource(), GetSymbol(), GetTf(), /*[*/ GetDepth(), + GetDeviation(), GetBackstep() /*]*/, _mode, _ishift, THIS_PTR); + break; default: SetUserError(ERR_INVALID_PARAMETER); break; diff --git a/Indicators/OHLC/Indi_OHLC.mqh b/Indicators/OHLC/Indi_OHLC.mqh index 7d7d26d93..c6c3d39ef 100644 --- a/Indicators/OHLC/Indi_OHLC.mqh +++ b/Indicators/OHLC/Indi_OHLC.mqh @@ -60,7 +60,7 @@ class Indi_OHLC : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); ENUM_APPLIED_PRICE _ap = PRICE_OPEN; switch (_mode) { diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index 74cd43db8..89b0f7279 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -62,7 +62,7 @@ class Indi_Price : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); return ChartStatic::iPrice(iparams.GetAppliedPrice(), GetSymbol(), GetTf(), _ishift); } diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index 033377c04..e1c991916 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -93,7 +93,7 @@ class Indi_Math : public Indicator { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index db392ce69..c32f45482 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -86,7 +86,7 @@ class Indi_TickMt : public IndicatorTick { * This method allows user to modify the struct entry before it's added to cache. * This method is called on GetEntry() right after values are set. */ - virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = -1) { + virtual void GetEntryAlter(IndicatorDataEntry &_entry, int _shift = 0) { IndicatorTick::GetEntryAlter(_entry, _shift); _entry.timestamp = _entry.timestamp > 0 ? _entry.timestamp : tick.time; }; diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 60a416e0c..87b63f56b 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -83,6 +83,11 @@ int OnInit() { void OnTick() { chart.OnTick(); + // All indicators should execute its OnTick() method for every platform tick. + for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { + iter.Value().Ptr().OnTick(); + } + if (chart.IsNewBar()) { bar_processed++; if (indis.Size() == 0) { From f4c946d6c07bc7bf324a7a8690eac23019fa57e0 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Sat, 11 Dec 2021 01:24:36 +0100 Subject: [PATCH 41/81] WIP. AMA now requires refactor back to be parent of Indicator or something similar. --- Indicator/IndicatorCandle.h | 11 ++++++++ Indicator/tests/classes/IndicatorTickReal.h | 7 +++++ IndicatorBase.h | 29 ++++++++++++++++++++- Indicators/Indi_AMA.mqh | 3 ++- tests/IndicatorsTest.mq5 | 11 ++++++-- 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 6a36c4312..19b2478a1 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -92,9 +92,13 @@ class IndicatorCandle : public IndicatorBase { CandleOCTOHLC _candle = icdata.GetByKey(_candle_time); if (!_candle.IsValid()) { +#ifdef __debug__ Print(GetFullName(), ": Missing candle at shift ", _index, " (", TimeToString(_candle_time), ")"); +#endif } else { +#ifdef __debug__verbose_ Print(GetFullName(), ": Retrieving candle at shift ", _index, " (", TimeToString(_candle_time), ")"); +#endif } return CandleToEntry(_candle_time, _candle); @@ -169,8 +173,10 @@ class IndicatorCandle : public IndicatorBase { void UpdateCandle(long _tick_timestamp, double _price) { long _candle_timestamp = CalcCandleTimestamp(_tick_timestamp); +#ifdef __debug_verbose__ Print("Updating candle for ", GetFullName(), " at candle ", TimeToString(_candle_timestamp), " from tick at ", TimeToString(_tick_timestamp)); +#endif CandleOCTOHLC _candle(_price, _price, _price, _price, _tick_timestamp, _tick_timestamp); if (icdata.KeyExists(_candle_timestamp)) { @@ -307,6 +313,11 @@ class IndicatorCandle : public IndicatorBase { return _result; } + + /** + * Get indicator type. + */ + ENUM_INDICATOR_TYPE GetType() override { return icparams.itype; } }; #endif diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index a8884c3a6..a654c4da8 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -50,13 +50,17 @@ class IndicatorTickReal : public IndicatorTick void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { // Feeding base indicator with historic entries of this indicator. +#ifdef __debug__ Print(GetFullName(), " became a data source for ", _base_indi.GetFullName()); +#endif #ifndef __MQL4__ int _ticks_to_emit = 1000; +#ifdef __debug_verbose__ Print(_base_indi.GetFullName(), " will be now filled with ", _ticks_to_emit, " historical entries generated by " + GetFullName()); +#endif static MqlTick _ticks[]; ArrayResize(_ticks, 0); @@ -97,7 +101,10 @@ class IndicatorTickReal : public IndicatorTick // Copying only the last tick. int _num_copied = CopyTicks(GetSymbol(), _ticks, COPY_TICKS_INFO, 0, 1); +#ifdef __debug_verbose__ Print("TickReal: ", TimeToString(_ticks[0].time), " = ", _ticks[0].bid); +#endif + double _ask = _ticks[0].ask; double _bid = _ticks[0].bid; long _time = _ticks[0].time; diff --git a/IndicatorBase.h b/IndicatorBase.h index 5d74af976..54b681fdf 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -71,6 +71,7 @@ class IndicatorBase : public Chart { int indi_src_mode; // Mode of source indicator IndicatorCalculateCache cache; ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. + long last_tick_time; // Time of the last Tick() call. public: /* Indicator enumerations */ @@ -94,6 +95,7 @@ class IndicatorBase : public Chart { calc_start_bar = 0; is_fed = false; indi_src = NULL; + last_tick_time = 0; } /** @@ -103,6 +105,7 @@ class IndicatorBase : public Chart { calc_start_bar = 0; is_fed = false; indi_src = NULL; + last_tick_time = 0; } /** @@ -351,7 +354,7 @@ class IndicatorBase : public Chart { /** * Get name of the indicator. */ - virtual string GetName() { return ""; } + virtual string GetName() { return EnumToString(GetType()); } /** * Get full name of the indicator (with "over ..." part). @@ -498,6 +501,30 @@ class IndicatorBase : public Chart { return _result; } + void Tick() { + long _current_time = TimeCurrent(); + + if (last_tick_time == _current_time) { + // We've already ticked. + return; + } + + last_tick_time = _current_time; + + // Overridable OnTick() method. + OnTick(); + + if (HasDataSource()) { + // Ticking data source if not yet ticked.s + GetDataSource().Tick(); + } + + // Also ticking all used indicators if they've not yet ticked. + for (DictStructIterator> iter = indicators.Begin(); iter.IsValid(); ++iter) { + iter.Value().Ptr().Tick(); + } + } + virtual void OnTick() {} /* Data representation methods */ diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 4342dad6c..ea4481f09 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -56,7 +56,8 @@ struct IndiAMAParams : IndicatorTfParams { IndiAMAParams(IndiAMAParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; tf = _tf; - }; + } + 5; }; /** diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 87b63f56b..cdb3b16cc 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -78,14 +78,14 @@ int OnInit() { } /** - * Implements Tick event handler. + * Implements Tick event handler . */ void OnTick() { chart.OnTick(); // All indicators should execute its OnTick() method for every platform tick. for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { - iter.Value().Ptr().OnTick(); + iter.Value().Ptr().Tick(); } if (chart.IsNewBar()) { @@ -109,6 +109,13 @@ void OnTick() { IndicatorBase* _indi = iter.Value().Ptr(); _indi.OnTick(); IndicatorDataEntry _entry(_indi.GetEntry()); + + if (_indi.GetType() == INDI_AMA) { + PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); + } else { + continue; + } + if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { if (_entry.IsValid()) { PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); From 761facece28196e4263db29e2c030312a25bd0a4 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 15 Dec 2021 18:19:43 +0100 Subject: [PATCH 42/81] WIP. Introduces IndicatorCandleSource and IndicatorTickSource indicator class bases. Also reverted back to using Indicator as parent for IndicatorCandle (and later for IndicatorTick). --- Indicator.mqh | 143 +++++++-------- Indicator/IndicatorCandle.h | 199 +++++++-------------- Indicator/IndicatorCandleSource.h | 99 ++++++++++ Indicator/IndicatorTf.h | 6 +- Indicator/IndicatorTickSource.h | 83 +++++++++ Indicator/tests/classes/IndicatorTfDummy.h | 5 +- IndicatorBase.h | 18 +- Indicators/Indi_AMA.mqh | 58 +++--- tests/IndicatorsTest.mq5 | 5 +- 9 files changed, 360 insertions(+), 256 deletions(-) create mode 100644 Indicator/IndicatorCandleSource.h create mode 100644 Indicator/IndicatorTickSource.h diff --git a/Indicator.mqh b/Indicator.mqh index 665ca3060..cfcc683f6 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -720,6 +720,15 @@ class Indicator : public IndicatorBase { _result = _source.Ptr(); } } + } else { + // Requesting potential data source. + IndicatorBase* _ds = OnDataSourceRequest(); + + if (_ds != NULL) { + // Initializing with new data source. + SetDataSource(_ds); + iparams.SetDataSourceType(IDATA_INDICATOR); + } } ValidateDataSource(&this, _result); @@ -735,7 +744,17 @@ class Indicator : public IndicatorBase { /** * Whether data source is selected. */ - virtual bool HasDataSource() { return GetDataSourceRaw() != NULL || iparams.GetDataSourceId() != -1; } + virtual bool HasDataSource(bool _try_initialize = false) { + if (iparams.GetDataSourceId() != -1) { + return true; + } + + if (GetDataSourceRaw() == NULL && _try_initialize) { + SetDataSource(OnDataSourceRequest()); + } + + return GetDataSourceRaw() != NULL; + } /** * Gets indicator's params. @@ -775,14 +794,6 @@ class Indicator : public IndicatorBase { */ string GetName() { return iparams.name; } - /** - * Get full name of the indicator (with "over ..." part). - */ - string GetFullName() { - return iparams.name + "[" + IntegerToString(iparams.GetMaxModes()) + "]" + - (HasDataSource() ? (" (over " + GetDataSource().GetFullName() + ")") : ""); - } - /** * Get more descriptive name of the indicator. */ @@ -816,19 +827,6 @@ class Indicator : public IndicatorBase { Chart::Set(_param, _value); } - /** - * Sets indicator data source. - */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { - if (indi_src.IsSet() && indi_src.Ptr() != _indi) { - indi_src.Ptr().RemoveListener(THIS_PTR); - } - indi_src = _indi; - indi_src.Ptr().AddListener(THIS_PTR); - iparams.SetDataSource(-1, _input_mode); - indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); - } - /** * Sets name of the indicator. */ @@ -966,63 +964,7 @@ class Indicator : public IndicatorBase { return true; } - /** - * Returns shift at which the last known valid entry exists for a given - * period (or from the start, when period is not specified). - */ - /* - bool GetLastValidEntryShift(int& out_shift, int period = 0) { - out_shift = 0; - - while (true) { - if ((period != 0 && out_shift >= period) || !HasValidEntry(out_shift + 1)) - return out_shift > 0; // Current shift is always invalid. - - ++out_shift; - } - - return out_shift > 0; - }*/ - - /** - * Returns shift at which the oldest known valid entry exists for a given - * period (or from the start, when period is not specified). - */ - /* - bool GetOldestValidEntryShift(int& out_shift, int& out_num_valid, int shift = 0, int period = 0) { - bool found = false; - // Counting from previous up to previous - period. - for (out_shift = shift + 1; out_shift < shift + period + 1; ++out_shift) { - if (!HasValidEntry(out_shift)) { - --out_shift; - out_num_valid = out_shift - shift; - return found; - } else - found = true; - } - - --out_shift; - out_num_valid = out_shift - shift; - return found; - } - */ - - /** - * Checks whether indicator has valid at least given number of last entries - * (counting from given shift or 0). - */ - /* - bool HasAtLeastValidLastEntries(int period, int shift = 0) { - for (int i = 0; i < period; ++i) - if (!HasValidEntry(shift + i)) return false; - - return true; - } - */ - - // ENUM_IDATA_VALUE_RANGE GetIDataValueRange() { return iparams.idvrange; } - - virtual void OnTick() { + void OnTick() override { Chart::OnTick(); if (iparams.is_draw) { @@ -1033,6 +975,21 @@ class Indicator : public IndicatorBase { } } + /** + * Sets indicator data source. + */ + void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + if (indi_src.IsSet() && indi_src.Ptr() != _indi) { + indi_src.Ptr().RemoveListener(THIS_PTR); + } + indi_src = _indi; + if (_indi != NULL) { + indi_src.Ptr().AddListener(THIS_PTR); + iparams.SetDataSource(-1, _input_mode); + indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); + } + } + /* Data representation methods */ /* Virtual methods */ @@ -1087,6 +1044,19 @@ class Indicator : public IndicatorBase { return _result; } + /** + * Get full name of the indicator (with "over ..." part). + */ + string GetFullName() override { + return GetName() + "[" + IntegerToString(iparams.GetMaxModes()) + "]" + + (HasDataSource() ? (" (over " + GetDataSource().GetFullName() + ")") : ""); + } + + /** + * Get indicator type. + */ + ENUM_INDICATOR_TYPE GetType() override { return iparams.itype; } + /** * Update indicator. */ @@ -1163,9 +1133,22 @@ class Indicator : public IndicatorBase { * This method allows user to modify the struct entry before it's added to cache. * This method is called on GetEntry() right after values are set. */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _index = -1) { + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { _entry.AddFlags(_entry.GetDataTypeFlags(iparams.GetDataValueType())); }; + + /** + * Returns the indicator's entry value for the given shift and mode. + * + * @see: DataParamEntry. + * + * @return + * Returns DataParamEntry struct filled with a single value. + */ + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + return GetEntry(_ishift)[_mode]; + } }; #endif diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 19b2478a1..e1b0ecf52 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -31,16 +31,26 @@ // Includes. #include "../Buffer/BufferCandle.h" -#include "../IndicatorBase.h" +#include "../Indicator.mqh" + +enum ENUM_INDI_CANDLE_MODE { + INDI_CANDLE_MODE_PRICE_OPEN, + INDI_CANDLE_MODE_PRICE_HIGH, + INDI_CANDLE_MODE_PRICE_LOW, + INDI_CANDLE_MODE_PRICE_CLOSE, + INDI_CANDLE_MODE_SPREAD, + INDI_CANDLE_MODE_TICK_VOLUME, + INDI_CANDLE_MODE_VOLUME, + FINAL_INDI_CANDLE_MODE_ENTRY, +}; /** * Class to deal with candle indicators. */ template -class IndicatorCandle : public IndicatorBase { +class IndicatorCandle : public Indicator { protected: BufferCandle icdata; - TS icparams; protected: /* Protected methods */ @@ -53,7 +63,7 @@ class IndicatorCandle : public IndicatorBase { void Init() { icdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); icdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); - icparams.SetMaxModes(4); + iparams.SetMaxModes(4); } public: @@ -62,16 +72,13 @@ class IndicatorCandle : public IndicatorBase { /** * Class constructor. */ - IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { - icparams = _icparams; - if (_indi_src != NULL) { - SetDataSource(_indi_src, _indi_mode); - } + IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + : Indicator(_icparams, _indi_src, _indi_mode) { Init(); } - IndicatorCandle(ENUM_INDICATOR_TYPE _itype = INDI_CANDLE, int _shift = 0, string _name = "") { - icparams.SetIndicatorType(_itype); - icparams.SetShift(_shift); + IndicatorCandle(ENUM_INDICATOR_TYPE _itype = INDI_CANDLE, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, + string _name = "") + : Indicator(_itype, _tf, _shift, _name) { Init(); } @@ -87,7 +94,7 @@ class IndicatorCandle : public IndicatorBase { */ IndicatorDataEntry GetEntry(int _index) override { ResetLastError(); - unsigned int _ishift = _index >= 0 ? _index : icparams.GetShift(); + unsigned int _ishift = _index >= 0 ? _index : iparams.GetShift(); long _candle_time = CalcCandleTimestamp(GetBarTime(_ishift)); CandleOCTOHLC _candle = icdata.GetByKey(_candle_time); @@ -104,29 +111,6 @@ class IndicatorCandle : public IndicatorBase { return CandleToEntry(_candle_time, _candle); } - /** - * Alters indicator's struct value. - * - * This method allows user to modify the struct entry before it's added to cache. - * This method is called on GetEntry() right after values are set. - */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { - _entry.AddFlags(_entry.GetDataTypeFlags(icparams.GetDataValueType())); - }; - - /** - * Returns the indicator's entry value for the given shift and mode. - * - * @see: DataParamEntry. - * - * @return - * Returns DataParamEntry struct filled with a single value. - */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { - int _ishift = _shift >= 0 ? _shift : icparams.GetShift(); - return GetEntry(_ishift)[_mode]; - } - /** * Function should return true if resize can be made, or false to overwrite current slot. */ @@ -192,29 +176,58 @@ class IndicatorCandle : public IndicatorBase { * Calculates candle's timestamp from tick's timestamp. */ long CalcCandleTimestamp(long _tick_timestamp) { - return _tick_timestamp - _tick_timestamp % (icparams.GetSecsPerCandle()); + return _tick_timestamp - _tick_timestamp % (iparams.GetSecsPerCandle()); } /** * Called when data source emits new entry (historic or future one). */ - virtual void OnDataSourceEntry(IndicatorDataEntry& entry) { + void OnDataSourceEntry(IndicatorDataEntry& entry) override { // Updating candle from bid price. UpdateCandle(entry.timestamp, entry[1]); }; /** - * Sets indicator data source. - */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { - if (indi_src.IsSet() && indi_src.Ptr() != _indi) { - indi_src.Ptr().RemoveListener(THIS_PTR); + * Returns value storage of given kind. + */ + IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + switch (_type) { + case INDI_VS_TYPE_PRICE_OPEN: + return GetValueStorage(INDI_CANDLE_MODE_PRICE_OPEN); + case INDI_VS_TYPE_PRICE_HIGH: + return GetValueStorage(INDI_CANDLE_MODE_PRICE_HIGH); + case INDI_VS_TYPE_PRICE_LOW: + return GetValueStorage(INDI_CANDLE_MODE_PRICE_LOW); + case INDI_VS_TYPE_PRICE_CLOSE: + return GetValueStorage(INDI_CANDLE_MODE_PRICE_CLOSE); + case INDI_VS_TYPE_SPREAD: + return GetValueStorage(INDI_CANDLE_MODE_SPREAD); + case INDI_VS_TYPE_TICK_VOLUME: + return GetValueStorage(INDI_CANDLE_MODE_TICK_VOLUME); + case INDI_VS_TYPE_VOLUME: + return GetValueStorage(INDI_CANDLE_MODE_VOLUME); + default: + // Trying in parent class. + return Indicator::GetSpecificValueStorage(_type); } - indi_src = _indi; - if (_indi != NULL) { - indi_src.Ptr().AddListener(THIS_PTR); - icparams.SetDataSource(-1, _input_mode); - indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); + } + + /** + * Checks whether indicator support given value storage type. + */ + virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { + switch (_type) { + case INDI_VS_TYPE_PRICE_OPEN: + case INDI_VS_TYPE_PRICE_HIGH: + case INDI_VS_TYPE_PRICE_LOW: + case INDI_VS_TYPE_PRICE_CLOSE: + case INDI_VS_TYPE_SPREAD: + case INDI_VS_TYPE_TICK_VOLUME: + case INDI_VS_TYPE_VOLUME: + return true; + default: + // Trying in parent class. + return Indicator::HasSpecificValueStorage(_type); } } @@ -228,96 +241,6 @@ class IndicatorCandle : public IndicatorBase { } /* Virtual methods */ - - /** - * Checks if indicator entry is valid. - * - * @return - * Returns true if entry is valid (has valid values), otherwise false. - */ - virtual bool IsValidEntry(IndicatorDataEntry& _entry) { - bool _result = true; - _result &= _entry.timestamp > 0; - _result &= _entry.GetSize() > 0; - if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_REAL)) { - if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { - _result &= !_entry.HasValue(DBL_MAX); - _result &= !_entry.HasValue(NULL); - } else { - _result &= !_entry.HasValue(FLT_MAX); - _result &= !_entry.HasValue(NULL); - } - } else { - if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_UNSIGNED)) { - if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { - _result &= !_entry.HasValue(ULONG_MAX); - _result &= !_entry.HasValue(NULL); - } else { - _result &= !_entry.HasValue(UINT_MAX); - _result &= !_entry.HasValue(NULL); - } - } else { - if (_entry.CheckFlags(INDI_ENTRY_FLAG_IS_DOUBLED)) { - _result &= !_entry.HasValue(LONG_MAX); - _result &= !_entry.HasValue(NULL); - } else { - _result &= !_entry.HasValue(INT_MAX); - _result &= !_entry.HasValue(NULL); - } - } - } - return _result; - } - - /** - * Get full name of the indicator (with "over ..." part). - */ - string GetFullName() override { - return GetName() + "[" + IntegerToString(icparams.GetMaxModes()) + "]" + - (HasDataSource() ? (" (over " + GetDataSource().GetFullName() + ")") : ""); - } - - /** - * Whether data source is selected. - */ - bool HasDataSource() override { return GetDataSourceRaw() != NULL || icparams.GetDataSourceId() != -1; } - - /** - * Returns currently selected data source doing validation. - */ - IndicatorBase* GetDataSource() override { - IndicatorBase* _result = NULL; - - if (GetDataSourceRaw() != NULL) { - _result = GetDataSourceRaw(); - } else if (icparams.GetDataSourceId() != -1) { - int _source_id = icparams.GetDataSourceId(); - - if (indicators.KeyExists(_source_id)) { - _result = indicators[_source_id].Ptr(); - } else { - Ref _source = FetchDataSource((ENUM_INDICATOR_TYPE)_source_id); - - if (!_source.IsSet()) { - Alert(GetName(), " has no built-in source indicator ", _source_id); - DebugBreak(); - } else { - indicators.Set(_source_id, _source); - - _result = _source.Ptr(); - } - } - } - - ValidateDataSource(&this, _result); - - return _result; - } - - /** - * Get indicator type. - */ - ENUM_INDICATOR_TYPE GetType() override { return icparams.itype; } }; #endif diff --git a/Indicator/IndicatorCandleSource.h b/Indicator/IndicatorCandleSource.h new file mode 100644 index 000000000..47abebcd9 --- /dev/null +++ b/Indicator/IndicatorCandleSource.h @@ -0,0 +1,99 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../Indicator.mqh" +#include "tests/classes/IndicatorTfDummy.h" +#include "tests/classes/IndicatorTickReal.h" + +/** + * Indicator to be used with IndicatorCandle as a data source. + */ +template +class IndicatorCandleSource : public Indicator { + public: + /** + * Class constructor. + */ + IndicatorCandleSource(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + : Indicator(_iparams, _indi_src, _indi_mode) {} + IndicatorCandleSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} + IndicatorCandleSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, + string _name = "") + : Indicator(_itype, _tf, _shift, _name) {} + + /** + * Class deconstructor. + */ + ~IndicatorCandleSource() {} + + /** + * Sets indicator data source. + */ + void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + if (_indi == NULL) { + // Just deselecting data source. + Indicator::SetDataSource(_indi, _input_mode); + return; + } + + // We can only use data sources which supports all possible modes from IndicatorCandle. + bool _result = true; + + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_SPREAD); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_TICK_VOLUME); + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_VOLUME); + + if (!_result) { + Alert("Passed indicator ", _indi.GetFullName(), " does not define all required specific data storages!"); + DebugBreak(); + } + + Indicator::SetDataSource(_indi, _input_mode); + } + + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + IndicatorBase* OnDataSourceRequest() override { + // Defaulting to real platform ticks. + IndicatorBase* _indi_tick = + new IndicatorTickReal(GetSymbol(), GetTf(), "Ticker for Tf on IndicatorCandleSource-based indicator"); + + // Tf will work on real platform ticks. + IndicatorBase* _indi_tf = new IndicatorTfDummy(GetTf()); + _indi_tf.SetDataSource(_indi_tick); + + // Indicator will work on Tf, which will receive real platform ticks. + return _indi_tf; + } +}; diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index 21350c445..84fe4b7c0 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -56,7 +56,7 @@ class IndicatorTf : public IndicatorCandle { * Class constructor with timeframe enum. */ IndicatorTf(uint _spc) { - icparams.SetSecsPerCandle(_spc); + iparams.SetSecsPerCandle(_spc); Init(); } @@ -64,7 +64,7 @@ class IndicatorTf : public IndicatorCandle { * Class constructor with timeframe enum. */ IndicatorTf(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) { - icparams.SetSecsPerCandle(ChartTf::TfToSeconds(_tf)); + iparams.SetSecsPerCandle(ChartTf::TfToSeconds(_tf)); Init(); } @@ -72,7 +72,7 @@ class IndicatorTf : public IndicatorCandle { * Class constructor with timeframe index. */ IndicatorTf(ENUM_TIMEFRAMES_INDEX _tfi = 0) { - icparams.SetSecsPerCandle(ChartTf::TfToSeconds(ChartTf::IndexToTf(_tfi))); + iparams.SetSecsPerCandle(ChartTf::TfToSeconds(ChartTf::IndexToTf(_tfi))); Init(); } diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h new file mode 100644 index 000000000..1b6273b8f --- /dev/null +++ b/Indicator/IndicatorTickSource.h @@ -0,0 +1,83 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../Indicator.mqh" + +/** + * Indicator to be used with IndicatorTick as a data source. + */ +template +class IndicatorTickSource : public Indicator { + public: + /** + * Class constructor. + */ + IndicatorTickSource(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + : Indicator(_iparams, _indi_src, _indi_mode) {} + IndicatorTickSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} + IndicatorTickSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, + string _name = "") + : Indicator(_itype, _tf, _shift, _name) {} + + /** + * Class deconstructor. + */ + ~IndicatorCandleSource() {} + + /** + * Sets indicator data source. + */ + void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + if (_indi == NULL) { + // Just deselecting data source. + Indicator::SetDataSource(_indi, _input_mode); + return; + } + + // We can only use data sources which supports all possible modes from IndicatorTick. + bool _result = true; + + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_APPLIED); + + if (!_result) { + Alert("Passed indicator ", _indi.GetFullName(), " does not define all required specific data storages!"); + DebugBreak(); + } + + Indicator::SetDataSource(_indi, _input_mode); + } + + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + IndicatorBase* OnDataSourceRequest() override { + // Defaulting to platform ticks. + return new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal"); + } +}; diff --git a/Indicator/tests/classes/IndicatorTfDummy.h b/Indicator/tests/classes/IndicatorTfDummy.h index 7bd57829e..8414f4786 100644 --- a/Indicator/tests/classes/IndicatorTfDummy.h +++ b/Indicator/tests/classes/IndicatorTfDummy.h @@ -29,6 +29,9 @@ #pragma once #endif +// Includes. +#include "../../IndicatorTf.h" + // Params for dummy candle-based indicator. struct IndicatorTfDummyParams : IndicatorTfParams { IndicatorTfDummyParams(uint _spc = 60) : IndicatorTfParams(_spc) {} @@ -43,7 +46,7 @@ class IndicatorTfDummy : public IndicatorTf { IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {} IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {} - string GetName() override { return "IndicatorTfDummy(" + IntegerToString(icparams.spc) + ")"; } + string GetName() override { return "IndicatorTfDummy(" + IntegerToString(iparams.spc) + ")"; } void OnDataSourceEntry(IndicatorDataEntry& entry) override { // When overriding OnDataSourceEntry() we have to remember to call parent diff --git a/IndicatorBase.h b/IndicatorBase.h index 54b681fdf..5a7d200b7 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -299,6 +299,12 @@ class IndicatorBase : public Chart { return _result; } + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + virtual IndicatorBase* OnDataSourceRequest() { return NULL; } + /* Getters */ /** @@ -332,7 +338,7 @@ class IndicatorBase : public Chart { /** * Whether data source is selected. */ - virtual bool HasDataSource() { return false; } + virtual bool HasDataSource(bool _try_initialize = false) { return false; } /** * Returns currently selected data source doing validation. @@ -456,6 +462,11 @@ class IndicatorBase : public Chart { return NULL; } + /** + * Checks whether indicator support given value storage type. + */ + virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { return false; } + template T GetValue(int _index = 0, int _mode = 0) { T _out; @@ -514,8 +525,9 @@ class IndicatorBase : public Chart { // Overridable OnTick() method. OnTick(); - if (HasDataSource()) { - // Ticking data source if not yet ticked.s + // Checking and potentially initializing new data source. + if (HasDataSource(true) != NULL) { + // Ticking data source if not yet ticked. GetDataSource().Tick(); } diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index ea4481f09..abf35439b 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -22,14 +22,13 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator/IndicatorTf.h" -#include "../Indicator/tests/classes/IndicatorTickReal.h" +#include "../Indicator/IndicatorCandleSource.h" #include "../Storage/ValueStorage.h" #include "../Storage/ValueStorage.price.h" #include "Price/Indi_Price.mqh" // Structs. -struct IndiAMAParams : IndicatorTfParams { +struct IndiAMAParams : IndicatorParams { unsigned int period; unsigned int fast_period; unsigned int slow_period; @@ -44,6 +43,8 @@ struct IndiAMAParams : IndicatorTfParams { ama_shift(_ama_shift), applied_price(_ap) { SetDataValueRange(IDATA_RANGE_PRICE); + // Defaulting to on-indicator mode (will use real ticks from platform via IndicatorTickReal). + SetDataSourceMode(IDATA_INDICATOR); SetShift(_shift); switch (idstype) { case IDATA_ICUSTOM: @@ -57,32 +58,26 @@ struct IndiAMAParams : IndicatorTfParams { THIS_REF = _params; tf = _tf; } - 5; }; /** * Implements the AMA indicator. */ -class Indi_AMA : public IndicatorTf { +class Indi_AMA : public IndicatorCandleSource { public: /** * Class constructor. */ - Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTf(_p) { - icparams.SetIndicatorType(INDI_AMA); + Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL, int _indi_mode = 0) + : IndicatorCandleSource(_p, _indi_src, _indi_mode) { + iparams.SetIndicatorType(INDI_AMA); if (_indi_src != NULL) { - SetDataSource(_indi_src); - icparams.SetDataSourceType(IDATA_INDICATOR); + iparams.SetDataSourceType(IDATA_INDICATOR); } else { - // Defaulting to platform ticks. - SetDataSource(new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal")); - icparams.SetDataSourceType(IDATA_INDICATOR); } }; - Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTf(_tf) { - icparams.SetIndicatorType(INDI_AMA); - icparams.SetShift(_shift); - }; + Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorCandleSource(INDI_AMA, _tf, _shift){}; /** * Built-in version of AMA. @@ -229,14 +224,14 @@ class Indi_AMA : public IndicatorTf { */ virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; - int _ishift = _shift >= 0 ? _shift : icparams.GetShift(); - switch (icparams.idstype) { + int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + switch (iparams.idstype) { case IDATA_BUILTIN: _value = Indi_AMA::iAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), icparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), GetAMAShift() /*]*/, _mode, _ishift); break; @@ -251,32 +246,37 @@ class Indi_AMA : public IndicatorTf { return _value; } + /** + * Called when data source emits new entry (historic or future one). + */ + void OnDataSourceEntry(IndicatorDataEntry &entry) override { Print("New entry for AMA!"); }; + /* Getters */ /** * Get AMA shift. */ - unsigned int GetAMAShift() { return icparams.ama_shift; } + unsigned int GetAMAShift() { return iparams.ama_shift; } /** * Get period. */ - unsigned int GetPeriod() { return icparams.period; } + unsigned int GetPeriod() { return iparams.period; } /** * Get fast period. */ - unsigned int GetFastPeriod() { return icparams.fast_period; } + unsigned int GetFastPeriod() { return iparams.fast_period; } /** * Get slow period. */ - unsigned int GetSlowPeriod() { return icparams.slow_period; } + unsigned int GetSlowPeriod() { return iparams.slow_period; } /** * Get applied price. */ - ENUM_APPLIED_PRICE GetAppliedPrice() { return icparams.applied_price; } + ENUM_APPLIED_PRICE GetAppliedPrice() { return iparams.applied_price; } /* Setters */ @@ -285,7 +285,7 @@ class Indi_AMA : public IndicatorTf { */ void SetAMAShift(unsigned int _ama_shift) { istate.is_changed = true; - icparams.ama_shift = _ama_shift; + iparams.ama_shift = _ama_shift; } /** @@ -293,7 +293,7 @@ class Indi_AMA : public IndicatorTf { */ void SetPeriod(unsigned int _period) { istate.is_changed = true; - icparams.period = _period; + iparams.period = _period; } /** @@ -301,7 +301,7 @@ class Indi_AMA : public IndicatorTf { */ void SetFastPeriod(unsigned int _fast_period) { istate.is_changed = true; - icparams.fast_period = _fast_period; + iparams.fast_period = _fast_period; } /** @@ -309,7 +309,7 @@ class Indi_AMA : public IndicatorTf { */ void SetSlowPeriod(unsigned int _slow_period) { istate.is_changed = true; - icparams.slow_period = _slow_period; + iparams.slow_period = _slow_period; } /** @@ -317,6 +317,6 @@ class Indi_AMA : public IndicatorTf { */ void SetAppliedPrice(ENUM_APPLIED_PRICE _applied_price) { istate.is_changed = true; - icparams.applied_price = _applied_price; + iparams.applied_price = _applied_price; } }; diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index cdb3b16cc..3909a09d4 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -25,7 +25,8 @@ */ // Defines. -//#define __debug__ // Enables debug. +// #define __debug__ // Enables debug. +// #define __debug_verbose__ // Forward declaration. struct DataParamEntry; @@ -78,7 +79,7 @@ int OnInit() { } /** - * Implements Tick event handler . + * Implements Tick event handler. */ void OnTick() { chart.OnTick(); From fea144ae121d97480715f71bc8ee33a308d91642 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 16 Dec 2021 18:22:18 +0100 Subject: [PATCH 43/81] WIP. Almost working AMA indicator (still varies to much with original one). BWMFI somehow return 0 in first calculation buffer. --- Indicator.enum.h | 2 +- Indicator.mqh | 16 +++++++++------- Indicator/tests/classes/IndicatorTfDummy.h | 2 ++ IndicatorBase.h | 22 ++++++++++++++++++++++ Indicators/Indi_AMA.mqh | 8 ++------ Indicators/Indi_FractalAdaptiveMA.mqh | 2 +- Storage/ValueStorage.h | 4 ++++ tests/IndicatorsTest.mq5 | 11 +++++++++-- 8 files changed, 50 insertions(+), 17 deletions(-) diff --git a/Indicator.enum.h b/Indicator.enum.h index c98f42ce1..658423502 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -242,4 +242,4 @@ enum ENUM_INDI_VS_TYPE { INDI_VS_TYPE_PRICE_HIGH, INDI_VS_TYPE_PRICE_LOW, INDI_VS_TYPE_PRICE_CLOSE -}; \ No newline at end of file +}; diff --git a/Indicator.mqh b/Indicator.mqh index cfcc683f6..24750d256 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -147,22 +147,20 @@ class Indicator : public IndicatorBase { Indicator(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) : IndicatorBase(_iparams.GetTf(), NULL) { iparams = _iparams; - SetName(_iparams.name != "" ? _iparams.name : EnumToString(iparams.itype)); if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); + iparams.SetDataSourceType(IDATA_INDICATOR); } Init(); } Indicator(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorBase(_tf) { iparams = _iparams; - SetName(_iparams.name != "" ? _iparams.name : EnumToString(iparams.itype)); Init(); } Indicator(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : IndicatorBase(_tf) { iparams.SetIndicatorType(_itype); iparams.SetShift(_shift); - SetName(_name != "" ? _name : EnumToString(iparams.itype)); Init(); } @@ -183,7 +181,7 @@ class Indicator : public IndicatorBase { /* Buffer methods */ - virtual string CacheKey() { return GetName(); } + virtual string CacheKey() { return GetFullName(); } /** * Initializes a cached proxy between i*OnArray() methods and OnCalculate() @@ -720,7 +718,9 @@ class Indicator : public IndicatorBase { _result = _source.Ptr(); } } - } else { + } else if (iparams.GetDataSourceType() == IDATA_INDICATOR) { + // User sets data source's mode to On-Indicator, but not set data source via SetDataSource()! + // Requesting potential data source. IndicatorBase* _ds = OnDataSourceRequest(); @@ -749,7 +749,7 @@ class Indicator : public IndicatorBase { return true; } - if (GetDataSourceRaw() == NULL && _try_initialize) { + if (iparams.GetDataSourceType() == IDATA_INDICATOR && GetDataSourceRaw() == NULL && _try_initialize) { SetDataSource(OnDataSourceRequest()); } @@ -792,7 +792,9 @@ class Indicator : public IndicatorBase { /** * Get name of the indicator. */ - string GetName() { return iparams.name; } + string GetName() override { + return "(" + EnumToString(GetType()) + ")" + (iparams.name != "" ? (" " + iparams.name) : ""); + } /** * Get more descriptive name of the indicator. diff --git a/Indicator/tests/classes/IndicatorTfDummy.h b/Indicator/tests/classes/IndicatorTfDummy.h index 8414f4786..6680f07e0 100644 --- a/Indicator/tests/classes/IndicatorTfDummy.h +++ b/Indicator/tests/classes/IndicatorTfDummy.h @@ -54,7 +54,9 @@ class IndicatorTfDummy : public IndicatorTf { // create/update matching candle. IndicatorTf::OnDataSourceEntry(entry); +#ifdef __debug_indicator__ Print(GetFullName(), " got new tick at ", entry.timestamp, " (" + TimeToString(entry.timestamp) + "): ", entry.ToString()); +#endif } }; diff --git a/IndicatorBase.h b/IndicatorBase.h index 5a7d200b7..898d51f78 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -462,6 +462,28 @@ class IndicatorBase : public Chart { return NULL; } + virtual IValueStorage* GetSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { + switch (_ap) { + case PRICE_OPEN: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + case PRICE_HIGH: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + case PRICE_LOW: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + case PRICE_CLOSE: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + default: + Print("Error: Invalid applied price " + EnumToString(_ap) + + ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " + "IndicatorBase::GetSpecificAppliedPriceValueStorage()!"); + DebugBreak(); + return NULL; + } + } + /** * Checks whether indicator support given value storage type. */ diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index abf35439b..3238fcd07 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -36,7 +36,7 @@ struct IndiAMAParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructor. 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) + ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) : period(_period), fast_period(_fast_period), slow_period(_slow_period), @@ -71,10 +71,6 @@ class Indi_AMA : public IndicatorCandleSource { Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL, int _indi_mode = 0) : IndicatorCandleSource(_p, _indi_src, _indi_mode) { iparams.SetIndicatorType(INDI_AMA); - if (_indi_src != NULL) { - iparams.SetDataSourceType(IDATA_INDICATOR); - } else { - } }; Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorCandleSource(INDI_AMA, _tf, _shift){}; @@ -125,7 +121,7 @@ class Indi_AMA : public IndicatorCandleSource { static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { - INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( + INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_AMA_ON_" + _indi.GetFullName(), _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, (int)_ap)); diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 63b2b1246..a9d1810ac 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -69,7 +69,7 @@ class Indi_FrAMA : public Indicator { #else INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, Util::MakeKey("Indi_FrAMA", _ma_period, _ma_shift, (int)_ap)); - return iFrAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _ma_period, _ma_shift, _mode, _shift, _ap, _cache); + return iFrAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _ma_period, _ma_shift, _ap, _mode, _shift, _cache); #endif } diff --git a/Storage/ValueStorage.h b/Storage/ValueStorage.h index 0348eb0c5..ea2730712 100644 --- a/Storage/ValueStorage.h +++ b/Storage/ValueStorage.h @@ -91,6 +91,10 @@ enum ENUM_IPEAK { IPEAK_LOWEST, IPEAK_HIGHEST }; ValueStorage *_price = INDI.GetValueStorage(APPLIED_PRICE); \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) +#define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC(INDI, SYMBOL, TF, APPLIED_PRICE, KEY) \ + ValueStorage *_price = INDI.GetSpecificAppliedPriceValueStorage(APPLIED_PRICE); \ + INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) + #define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(INDI, SYMBOL, TF, KEY) \ ValueStorage *_time = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_TIME); \ ValueStorage *_tick_volume = (ValueStorage *)INDI.GetSpecificValueStorage(INDI_VS_TYPE_TICK_VOLUME); \ diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 3909a09d4..918c3e734 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -112,9 +112,9 @@ void OnTick() { IndicatorDataEntry _entry(_indi.GetEntry()); if (_indi.GetType() == INDI_AMA) { - PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); + // PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); } else { - continue; + // continue; } if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { @@ -422,8 +422,15 @@ bool InitIndicators() { // AMA. IndiAMAParams ama_params(); + ama_params.SetDataSourceType(IDATA_INDICATOR); indis.Push(new Indi_AMA(ama_params)); + // Original AMA. + IndiAMAParams ama_params_orig(); + ama_params_orig.SetName("Original AMA to compare"); + ama_params_orig.SetDataSourceType(IDATA_BUILTIN); + indis.Push(new Indi_AMA(ama_params_orig)); + // Chaikin Oscillator. IndiCHOParams cho_params(); indis.Push(new Indi_CHO(cho_params)); From 0e1452722ec9da881f57f9b72ce19bd55c6b458e Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 22 Dec 2021 19:45:18 +0100 Subject: [PATCH 44/81] WIP. Partially working Tick/Candle/TickOrCandle indicators differentiation and automatic value (price) storage fetching after SetDataSource(). --- DrawIndicator.mqh | 1 - Indicator.enum.h | 35 ++++++------ Indicator.mqh | 2 +- Indicator.struct.h | 4 +- Indicator/IndicatorCandle.h | 2 +- Indicator/IndicatorCandleSource.h | 11 +++- Indicator/IndicatorTick.h | 2 +- Indicator/IndicatorTickOrCandleSource.h | 72 +++++++++++++++++++++++++ Indicator/IndicatorTickSource.h | 53 ++++++++++++++++-- IndicatorBase.h | 11 +++- Indicators/Bitwise/Indi_Candle.mqh | 9 ++-- Indicators/Bitwise/Indi_Pattern.mqh | 9 ++-- Indicators/Indi_AC.mqh | 8 +-- Indicators/Indi_AD.mqh | 8 +-- Indicators/Indi_ADX.mqh | 8 +-- Indicators/Indi_ADXW.mqh | 9 ++-- Indicators/Indi_AMA.mqh | 9 ++-- Indicators/Indi_AO.mqh | 8 +-- Indicators/Indi_ASI.mqh | 8 +-- Indicators/Indi_ATR.mqh | 8 +-- Indicators/Indi_Alligator.mqh | 9 ++-- Indicators/Indi_AppliedPrice.mqh | 9 ++-- Indicators/Indi_BWMFI.mqh | 16 +++--- Indicators/Indi_BWZT.mqh | 7 +-- Indicators/Indi_Bands.mqh | 8 +-- Indicators/Indi_BearsPower.mqh | 9 ++-- Indicators/Indi_BullsPower.mqh | 9 ++-- Indicators/Indi_CCI.mqh | 8 +-- Indicators/Indi_CHO.mqh | 9 ++-- Indicators/Indi_CHV.mqh | 9 ++-- Indicators/Indi_ColorBars.mqh | 9 ++-- Indicators/Indi_ColorCandlesDaily.mqh | 8 +-- Indicators/Indi_ColorLine.mqh | 9 ++-- Indicators/Indi_CustomMovingAverage.mqh | 8 +-- Indicators/Indi_DEMA.mqh | 9 ++-- Indicators/Indi_DeMarker.mqh | 10 ++-- Indicators/Indi_Demo.mqh | 9 ++-- Indicators/Indi_DetrendedPrice.mqh | 8 +-- Indicators/Indi_Drawer.mqh | 9 ++-- Indicators/Indi_Envelopes.mqh | 9 ++-- Indicators/Indi_Force.mqh | 9 ++-- Indicators/Indi_FractalAdaptiveMA.mqh | 10 ++-- Indicators/Indi_Fractals.mqh | 10 ++-- Indicators/Indi_Gator.mqh | 9 ++-- Indicators/Indi_HeikenAshi.mqh | 9 ++-- Indicators/Indi_Ichimoku.mqh | 10 ++-- Indicators/Indi_Killzones.mqh | 9 ++-- Indicators/Indi_MA.mqh | 37 +++++++++++-- Indicators/Indi_MACD.mqh | 9 ++-- Indicators/Indi_MFI.mqh | 8 +-- Indicators/Indi_MassIndex.mqh | 9 ++-- Indicators/Indi_Momentum.mqh | 10 ++-- Indicators/Indi_OBV.mqh | 8 +-- Indicators/Indi_OsMA.mqh | 9 ++-- Indicators/Indi_Pivot.mqh | 7 +-- Indicators/Indi_PriceChannel.mqh | 8 +-- Indicators/Indi_PriceFeeder.mqh | 11 ++-- Indicators/Indi_PriceVolumeTrend.mqh | 8 +-- Indicators/Indi_RS.mqh | 10 ++-- Indicators/Indi_RSI.mqh | 8 +-- Indicators/Indi_RVI.mqh | 8 +-- Indicators/Indi_RateOfChange.mqh | 8 +-- Indicators/Indi_SAR.mqh | 8 +-- Indicators/Indi_StdDev.mqh | 8 +-- Indicators/Indi_Stochastic.mqh | 9 ++-- Indicators/Indi_TEMA.mqh | 9 ++-- Indicators/Indi_TRIX.mqh | 9 ++-- Indicators/Indi_UltimateOscillator.mqh | 8 +-- Indicators/Indi_VIDYA.mqh | 9 ++-- Indicators/Indi_VROC.mqh | 9 ++-- Indicators/Indi_Volumes.mqh | 9 ++-- Indicators/Indi_WPR.mqh | 8 +-- Indicators/Indi_WilliamsAD.mqh | 9 ++-- Indicators/Indi_ZigZag.mqh | 9 ++-- Indicators/Indi_ZigZagColor.mqh | 9 ++-- Indicators/OHLC/Indi_OHLC.mqh | 9 ++-- Indicators/Price/Indi_Price.mqh | 59 ++++++++++++++++++-- Indicators/Special/Indi_Math.mqh | 9 ++-- tests/IndicatorsTest.mq5 | 2 +- 79 files changed, 566 insertions(+), 308 deletions(-) create mode 100644 Indicator/IndicatorTickOrCandleSource.h diff --git a/DrawIndicator.mqh b/DrawIndicator.mqh index 7017a81eb..2888b77cf 100644 --- a/DrawIndicator.mqh +++ b/DrawIndicator.mqh @@ -32,7 +32,6 @@ // Includes. #include "DictObject.mqh" #include "Draw.mqh" -#include "Indicator.mqh" #include "Object.mqh" // Forward declaration. diff --git a/Indicator.enum.h b/Indicator.enum.h index 658423502..563282745 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -40,7 +40,7 @@ enum ENUM_INDICATOR_ACTION { FINAL_INDICATOR_ACTION_ENTRY }; -/* Define type of indicators. */ +/* Define type of */ enum ENUM_INDICATOR_TYPE { INDI_NONE = 0, // (None) INDI_AC, // Accelerator Oscillator @@ -101,12 +101,12 @@ enum ENUM_INDICATOR_TYPE { INDI_PRICE_FEEDER, // Indicator which returns prices from custom array INDI_PRICE_VOLUME_TREND, // Price and Volume Trend INDI_RATE_OF_CHANGE, // Rate of Change - INDI_RS, // Indi_Math-based RSI indicator. + INDI_RS, // Indi_Math-based RSI INDI_RSI, // Relative Strength Index INDI_RSI_ON_PRICE, // Relative Strength Index (RSI) (on Price) INDI_RVI, // Relative Vigor Index INDI_SAR, // Parabolic SAR - INDI_SPECIAL_MATH, // Math operations over given indicator. + INDI_SPECIAL_MATH, // Math operations over given INDI_STDDEV, // Standard Deviation INDI_STDDEV_ON_MA_SMA, // Standard Deviation on Moving Average in SMA mode INDI_STDDEV_ON_PRICE, // Standard Deviation (on Price) @@ -132,7 +132,7 @@ enum ENUM_INDICATOR_TYPE { FINAL_INDICATOR_TYPE_ENTRY }; -/* Defines type of source data for indicator. */ +/* Defines type of source data for */ enum ENUM_IDATA_SOURCE_TYPE { IDATA_BUILTIN = 0, // Platform built-in IDATA_CHART, // Chart calculation @@ -154,7 +154,7 @@ enum ENUM_IDATA_VALUE_RANGE { IDATA_RANGE_UNKNOWN }; -// Indicator line identifiers used in ADX and ADXW indicators. +// Indicator line identifiers used in ADX and ADXW enum ENUM_INDI_ADX_LINE { #ifdef __MQL4__ LINE_MAIN_ADX = MODE_MAIN, // Base indicator line. @@ -176,7 +176,7 @@ enum ENUM_INDICATOR_INDEX { FINAL_ENUM_INDICATOR_INDEX = 3 // Should be the last one. Used to calculate the number of enum items. }; -/* Indicator line identifiers used in Envelopes and Fractals indicators. */ +/* Indicator line identifiers used in Envelopes and Fractals */ enum ENUM_LO_UP_LINE { #ifdef __MQL4__ LINE_UPPER = MODE_UPPER, // Upper line. @@ -189,7 +189,7 @@ enum ENUM_LO_UP_LINE { }; /** - * Indicator line identifiers used in MACD, RVI and Stochastic indicators. + * Indicator line identifiers used in MACD, RVI and Stochastic * * @see: * - https://docs.mql4.com/constants/indicatorconstants/lines @@ -234,12 +234,17 @@ enum INDICATOR_ENTRY_FLAGS { // Storage type for IndicatorBase::GetSpecificValueStorage(). enum ENUM_INDI_VS_TYPE { - INDI_VS_TYPE_TIME, - INDI_VS_TYPE_TICK_VOLUME, - INDI_VS_TYPE_VOLUME, - INDI_VS_TYPE_SPREAD, - INDI_VS_TYPE_PRICE_OPEN, - INDI_VS_TYPE_PRICE_HIGH, - INDI_VS_TYPE_PRICE_LOW, - INDI_VS_TYPE_PRICE_CLOSE + INDI_VS_TYPE_TIME, // Candle. + INDI_VS_TYPE_TICK_VOLUME, // Candle. + INDI_VS_TYPE_VOLUME, // Candle. + INDI_VS_TYPE_SPREAD, // Candle. + INDI_VS_TYPE_PRICE_OPEN, // Candle. + INDI_VS_TYPE_PRICE_HIGH, // Candle. + INDI_VS_TYPE_PRICE_LOW, // Candle. + INDI_VS_TYPE_PRICE_CLOSE, // Candle. + INDI_VS_TYPE_PRICE_MEDIAN, // Candle. + INDI_VS_TYPE_PRICE_TYPICAL, // Candle. + INDI_VS_TYPE_PRICE_WEIGHTED, // Candle. + INDI_VS_TYPE_PRICE_BID, // Tick. + INDI_VS_TYPE_PRICE_ASK, // Tick. }; diff --git a/Indicator.mqh b/Indicator.mqh index 24750d256..8687a702c 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -980,7 +980,7 @@ class Indicator : public IndicatorBase { /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { if (indi_src.IsSet() && indi_src.Ptr() != _indi) { indi_src.Ptr().RemoveListener(THIS_PTR); } diff --git a/Indicator.struct.h b/Indicator.struct.h index 782ab22c9..4479aeea4 100644 --- a/Indicator.struct.h +++ b/Indicator.struct.h @@ -437,7 +437,7 @@ struct IndicatorParams { idstype(_idstype), idvrange(IDATA_RANGE_UNKNOWN), indi_data_source_id(-1), - indi_data_source_mode(0), + indi_data_source_mode(-1), itype(_itype), is_draw(false), indi_color(clrNONE), @@ -454,7 +454,7 @@ struct IndicatorParams { idstype(_idstype), idvrange(IDATA_RANGE_UNKNOWN), indi_data_source_id(-1), - indi_data_source_mode(0), + indi_data_source_mode(-1), is_draw(false), indi_color(clrNONE), draw_window(0) { diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index e1b0ecf52..29c4fbd2e 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -215,7 +215,7 @@ class IndicatorCandle : public Indicator { /** * Checks whether indicator support given value storage type. */ - virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { + bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { switch (_type) { case INDI_VS_TYPE_PRICE_OPEN: case INDI_VS_TYPE_PRICE_HIGH: diff --git a/Indicator/IndicatorCandleSource.h b/Indicator/IndicatorCandleSource.h index 47abebcd9..2d721fb8a 100644 --- a/Indicator/IndicatorCandleSource.h +++ b/Indicator/IndicatorCandleSource.h @@ -54,7 +54,7 @@ class IndicatorCandleSource : public Indicator { /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { if (_indi == NULL) { // Just deselecting data source. Indicator::SetDataSource(_indi, _input_mode); @@ -80,6 +80,15 @@ class IndicatorCandleSource : public Indicator { Indicator::SetDataSource(_indi, _input_mode); } + /** + * Called when user tries to set given data source. Could be used to check if indicator implements all required value + * storages. + */ + bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) override { + // @todo Make use of this method. + return true; + } + /** * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on * some data source. diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 79784d472..c5ad92d86 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -165,7 +165,7 @@ class IndicatorTick : public IndicatorBase { /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) { + void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) { indi_src = _indi; itparams.SetDataSource(-1, _input_mode); } diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h new file mode 100644 index 000000000..b7bc25265 --- /dev/null +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -0,0 +1,72 @@ +//+------------------------------------------------------------------+ +//| 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 . + * + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../Indicator.mqh" +#include "tests/classes/IndicatorTickReal.h" + +/** + * Indicator to be used with IndicatorTick or IndicatorCandle as a data source. + * + * In order it to work with + */ +template +class IndicatorTickOrCandleSource : public Indicator { + public: + /** + * Class constructor. + */ + IndicatorTickOrCandleSource(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + : Indicator(_iparams, _indi_src, _indi_mode) {} + IndicatorTickOrCandleSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} + IndicatorTickOrCandleSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, + string _name = "") + : Indicator(_itype, _tf, _shift, _name) {} + + /** + * Class deconstructor. + */ + ~IndicatorTickOrCandleSource() {} + + /** + * Called when user tries to set given data source. Could be used to check if indicator implements all required value + * storages. + */ + bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) override { + // @todo Make use of this method. + return true; + } + + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + IndicatorBase* OnDataSourceRequest() override { + // Defaulting to platform ticks. + return new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal"); + } +}; diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h index 1b6273b8f..58800c0b8 100644 --- a/Indicator/IndicatorTickSource.h +++ b/Indicator/IndicatorTickSource.h @@ -47,12 +47,12 @@ class IndicatorTickSource : public Indicator { /** * Class deconstructor. */ - ~IndicatorCandleSource() {} + ~IndicatorTickSource() {} /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) override { + void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { if (_indi == NULL) { // Just deselecting data source. Indicator::SetDataSource(_indi, _input_mode); @@ -62,16 +62,61 @@ class IndicatorTickSource : public Indicator { // We can only use data sources which supports all possible modes from IndicatorTick. bool _result = true; - _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_APPLIED); + if (_input_mode == -1) { + // Source mode which acts as an applied price wasn't selected, so we have to ensure that source is a Tick + // indicator. Valid only if implements bid or ask price. + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_BID) || + _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); + } else { + // Applied price selected. We will select source indicator only if it provides price buffer for given applied + // price. + switch (_input_mode) { + case PRICE_OPEN: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + break; + case PRICE_HIGH: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + break; + case PRICE_LOW: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + break; + case PRICE_CLOSE: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + break; + case PRICE_MEDIAN: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_MEDIAN); + break; + case PRICE_TYPICAL: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_TYPICAL); + break; + case PRICE_WEIGHTED: + _result &= _indi.HasSpecificValueStorage(INDI_VS_TYPE_PRICE_WEIGHTED); + break; + default: + Alert("Invalid input mode ", _input_mode, " for indicator ", _indi.GetFullName(), + ". Must be one one PRICE_(OPEN|HIGH|LOW|CLOSE|MEDIAN|TYPICAL|WEIGHTED)!"); + DebugBreak(); + } + } if (!_result) { - Alert("Passed indicator ", _indi.GetFullName(), " does not define all required specific data storages!"); + Alert("Passed indicator ", _indi.GetFullName(), + " does not provide required data storage(s)! Mode selected: ", _input_mode); DebugBreak(); } Indicator::SetDataSource(_indi, _input_mode); } + /** + * Called when user tries to set given data source. Could be used to check if indicator implements all required value + * storages. + */ + bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) override { + // @todo Make use of this method. + return true; + } + /** * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on * some data source. diff --git a/IndicatorBase.h b/IndicatorBase.h index 898d51f78..f0b0e4677 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -401,7 +401,7 @@ class IndicatorBase : public Chart { /** * Sets indicator data source. */ - virtual void SetDataSource(IndicatorBase* _indi, int _input_mode = 0) = NULL; + virtual void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) = NULL; /** * Sets data source's input mode. @@ -611,6 +611,15 @@ class IndicatorBase : public Chart { */ virtual void OnBecomeDataSourceFor(IndicatorBase* _base_indi){}; + /** + * Called when user tries to set given data source. Could be used to check if indicator implements all required value + * storages. + */ + virtual bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) { + _reason = "Indicator " + GetName() + " does not implement OnValidateDataSource()"; + return false; + } + /** * Returns indicator value for a given shift and mode. */ diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 40575e792..13c98aeed 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -23,7 +23,7 @@ // Includes. #include "../../Bar.struct.h" #include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" #include "../../Pattern.struct.h" #include "../../Serializer.mqh" #include "../Price/Indi_Price.mqh" @@ -47,13 +47,14 @@ struct CandleParams : IndicatorParams { /** * Implements Candle Pattern Detector. */ -class Indi_Candle : public Indicator { +class Indi_Candle : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Candle(CandleParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_CANDLE, _tf, _shift){}; + Indi_Candle(CandleParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_CANDLE, _tf, _shift){}; /** * Alters indicator's struct value. diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index fec403314..1e13c4217 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -23,7 +23,7 @@ // Includes. #include "../../Bar.struct.h" #include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" #include "../../Pattern.struct.h" #include "../../Serializer.mqh" #include "../Price/Indi_Price.mqh" @@ -46,13 +46,14 @@ struct IndiPatternParams : IndicatorParams { /** * Implements Pattern Detector. */ -class Indi_Pattern : public Indicator { +class Indi_Pattern : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Pattern(IndiPatternParams& _p, IndicatorBase* _indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PATTERN, _tf, _shift){}; + Indi_Pattern(IndiPatternParams& _p, IndicatorBase* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PATTERN, _tf, _shift){}; /** * Returns the indicator's value. diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 8c222b537..34f7863c8 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -49,13 +49,13 @@ struct IndiACParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_AC : public Indicator { +class Indi_AC : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_AC(IndiACParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_AC, _tf, _shift){}; + Indi_AC(IndiACParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift){}; /** * Returns the indicator value. diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index 8473fe8de..c91a29f1f 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -48,13 +48,13 @@ struct IndiADParams : IndicatorParams { /** * Implements the Accumulation/Distribution indicator. */ -class Indi_AD : public Indicator { +class Indi_AD : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_AD(IndiADParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_AD, _tf, _shift) { + Indi_AD(IndiADParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AD, _tf, _shift) { iparams.SetTf(_tf); }; diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 041d8b975..0301eec6e 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Price/Indi_Price.mqh" #ifndef __MQL4__ @@ -61,13 +61,13 @@ struct IndiADXParams : IndicatorParams { /** * Implements the Average Directional Movement Index indicator. */ -class Indi_ADX : public Indicator { +class Indi_ADX : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_ADX(IndiADXParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ADX, _tf, _shift) {} + Indi_ADX(IndiADXParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index bac89a6c8..dc199dae2 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.h" #include "../Storage/ValueStorage.price.h" #include "../Storage/ValueStorage.spread.h" @@ -55,13 +55,14 @@ struct IndiADXWParams : IndiADXParams { /** * Implements the Average Directional Movement Index indicator by Welles Wilder. */ -class Indi_ADXW : public Indicator { +class Indi_ADXW : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_ADXW(IndiADXWParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_ADXW(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ADXW, _tf, _shift){}; + Indi_ADXW(IndiADXWParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ADXW(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_ADXW, _tf, _shift){}; /** * Built-in version of ADX Wilder. diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 3238fcd07..206c2cb77 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator/IndicatorCandleSource.h" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.h" #include "../Storage/ValueStorage.price.h" #include "Price/Indi_Price.mqh" @@ -63,17 +63,16 @@ struct IndiAMAParams : IndicatorParams { /** * Implements the AMA indicator. */ -class Indi_AMA : public IndicatorCandleSource { +class Indi_AMA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL, int _indi_mode = 0) - : IndicatorCandleSource(_p, _indi_src, _indi_mode) { + : IndicatorTickOrCandleSource(_p, _indi_src, _indi_mode) { iparams.SetIndicatorType(INDI_AMA); }; - Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorCandleSource(INDI_AMA, _tf, _shift){}; + Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AMA, _tf, _shift){}; /** * Built-in version of AMA. diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index e65e367aa..c2f9e6d35 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -51,13 +51,13 @@ struct IndiAOParams : IndicatorParams { /** * Implements the Awesome oscillator. */ -class Indi_AO : public Indicator { +class Indi_AO : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_AO(IndiAOParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_AO, _tf, _shift){}; + Indi_AO(IndiAOParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift){}; /** * Returns the indicator value. diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 1f18b15a5..cccfc3a2a 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -46,13 +46,13 @@ struct IndiASIParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_ASI : public Indicator { +class Indi_ASI : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_ASI(IndiASIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ASI, _tf, _shift){}; + Indi_ASI(IndiASIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift){}; /** * Built-in version of ASI. diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index f0d65d2f1..3a6328447 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -52,13 +52,13 @@ struct IndiATRParams : IndicatorParams { * * Note: It doesn't give independent signals. It is used to define volatility (trend strength). */ -class Indi_ATR : public Indicator { +class Indi_ATR : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_ATR(IndiATRParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ATR, _tf, _shift){}; + Indi_ATR(IndiATRParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ATR, _tf, _shift){}; /** * Returns the indicator value. diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index 52acbfd76..ff8fe357d 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -95,14 +95,15 @@ struct IndiAlligatorParams : IndicatorParams { /** * Implements the Alligator indicator. */ -class Indi_Alligator : public Indicator { +class Indi_Alligator : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_Alligator(IndiAlligatorParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ADX, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift){}; /** * Returns the indicator value. diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index 90e78ed63..28d43b785 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "OHLC/Indi_OHLC.mqh" // Structs. @@ -44,7 +44,7 @@ struct IndiAppliedPriceParams : IndicatorParams { /** * Implements the "Applied Price over OHCL Indicator" indicator, e.g. over Indi_Price. */ -class Indi_AppliedPrice : public Indicator { +class Indi_AppliedPrice : public IndicatorTickOrCandleSource { protected: void OnInit() { if (!indi_src.IsSet()) { @@ -58,10 +58,11 @@ class Indi_AppliedPrice : public Indicator { * Class constructor. */ Indi_AppliedPrice(IndiAppliedPriceParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) { + : IndicatorTickOrCandleSource(_p, _indi_src) { OnInit(); }; - Indi_AppliedPrice(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PRICE, _tf, _shift) { + Indi_AppliedPrice(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift) { OnInit(); }; diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index b0e3e1853..cfb98b777 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -62,14 +62,14 @@ struct IndiBWIndiMFIParams : IndicatorParams { /** * Implements the Market Facilitation Index by Bill Williams indicator. */ -class Indi_BWMFI : public Indicator { +class Indi_BWMFI : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_BWMFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BWMFI, _tf, _shift) {} + Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_BWMFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_BWMFI, _tf, _shift) {} /** * Returns the indicator value. @@ -81,7 +81,7 @@ class Indi_BWMFI : public Indicator { static double iBWMFI(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, ENUM_BWMFI_BUFFER _mode = BWMFI_BUFFER, IndicatorBase *_obj = NULL) { #ifdef __MQL4__ - return ::iBWMFI(_symbol, _tf, _shift); + return ::iBWMFI(_symbol, _tf, _real_shift); #else // __MQL5__ int _handle = Object::IsValid(_obj) ? _obj.Get(IndicatorState::INDICATOR_STATE_PROP_HANDLE) : NULL; double _res[]; @@ -115,8 +115,10 @@ class Indi_BWMFI : public Indicator { * Returns the indicator's value. */ virtual IndicatorDataEntryValue GetEntryValue(int _mode = BWMFI_BUFFER, int _shift = 0) { + int _ishift = iparams.GetShift() + _shift; + double _value = EMPTY_VALUE; - int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + switch (iparams.idstype) { case IDATA_BUILTIN: istate.handle = istate.is_changed ? INVALID_HANDLE : istate.handle; diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 73d027824..70675404e 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -62,13 +62,14 @@ struct IndiBWZTParams : IndicatorParams { /** * Implements the Bill Williams' Zone Trade. */ -class Indi_BWZT : public Indicator { +class Indi_BWZT : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_BWZT(IndiBWZTParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_BWZT(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BWZT, _tf, _shift){}; + Indi_BWZT(IndiBWZTParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_BWZT(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_BWZT, _tf, _shift){}; /** * Built-in version of BWZT. diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index a368d6b85..09e36401e 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Indi_CCI.mqh" #include "Indi_Envelopes.mqh" #include "Indi_MA.mqh" @@ -86,14 +86,14 @@ struct IndiBandsParams : IndicatorParams { /** * Implements the Bollinger Bands® indicator. */ -class Indi_Bands : public Indicator { +class Indi_Bands : public IndicatorTickSource { public: /** * Class constructor. */ Indi_Bands(IndiBandsParams &_p, IndicatorBase *_indi_src = NULL, int _mode = 0) - : Indicator(_p, _indi_src, _mode) {} - Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BANDS, _tf, _shift) {} + : IndicatorTickSource(_p, _indi_src, _mode) {} + Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_BANDS, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index b2bb83164..dae950d35 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -51,14 +51,15 @@ struct IndiBearsPowerParams : IndicatorParams { /** * Implements the Bears Power indicator. */ -class Indi_BearsPower : public Indicator { +class Indi_BearsPower : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BEARS, _tf, _shift) {} + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_BEARS, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index 1e55f0010..520ef6ccb 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -51,14 +51,15 @@ struct IndiBullsPowerParams : IndicatorParams { /** * Implements the Bulls Power indicator. */ -class Indi_BullsPower : public Indicator { +class Indi_BullsPower : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_BULLS, _tf, _shift) {} + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_BULLS, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index ed4f71c4a..4e34df025 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickSource.h" #include "Indi_MA.mqh" #include "Indi_PriceFeeder.mqh" #include "Price/Indi_Price.mqh" @@ -58,13 +58,13 @@ struct IndiCCIParams : IndicatorParams { /** * Implements the Commodity Channel Index indicator. */ -class Indi_CCI : public Indicator { +class Indi_CCI : public IndicatorTickSource { public: /** * Class constructor. */ - Indi_CCI(IndiCCIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_CCI, _tf, _shift) {} + Indi_CCI(IndiCCIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_CCI, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index a42f126a7..5366e2651 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "../Util.h" #include "Indi_MA.mqh" @@ -54,13 +54,14 @@ struct IndiCHOParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_CHO : public Indicator { +class Indi_CHO : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_CHO(IndiCHOParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_CHAIKIN, _tf, _shift){}; + Indi_CHO(IndiCHOParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_CHAIKIN, _tf, _shift){}; /** * Built-in version of Chaikin Oscillator. diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 1c0c15119..145a03f59 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "../Util.h" #include "Indi_MA.mqh" @@ -55,13 +55,14 @@ struct IndiCHVParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_CHV : public Indicator { +class Indi_CHV : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_CHV(IndiCHVParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_CHAIKIN_V, _tf, _shift){}; + Indi_CHV(IndiCHVParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_CHAIKIN_V, _tf, _shift){}; /** * Built-in version of Chaikin Volatility. diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index ae5dfcd9e..7927d1fe2 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -42,14 +42,15 @@ struct IndiColorBarsParams : IndicatorParams { /** * Implements Color Bars */ -class Indi_ColorBars : public Indicator { +class Indi_ColorBars : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_ColorBars(IndiColorBarsParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_COLOR_BARS, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_COLOR_BARS, _tf, _shift){}; /** * "Built-in" version of Color Bars. diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 140320f7b..9348b8095 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -42,15 +42,15 @@ struct IndiColorCandlesDailyParams : IndicatorParams { /** * Implements Color Bars */ -class Indi_ColorCandlesDaily : public Indicator { +class Indi_ColorCandlesDaily : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_ColorCandlesDaily(IndiColorCandlesDailyParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_ColorCandlesDaily(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_COLOR_CANDLES_DAILY, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_COLOR_CANDLES_DAILY, _tf, _shift){}; /** * "Built-in" version of Color Candles Daily. diff --git a/Indicators/Indi_ColorLine.mqh b/Indicators/Indi_ColorLine.mqh index fcf734106..64adcf9dc 100644 --- a/Indicators/Indi_ColorLine.mqh +++ b/Indicators/Indi_ColorLine.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "Indi_MA.mqh" @@ -45,14 +45,15 @@ struct IndiColorLineParams : IndicatorParams { /** * Implements Color Bars */ -class Indi_ColorLine : public Indicator { +class Indi_ColorLine : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_ColorLine(IndiColorLineParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_COLOR_LINE, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_COLOR_LINE, _tf, _shift){}; /** * "Built-in" version of Color Line. diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index 664251971..e172c2b69 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" // Structs. struct IndiCustomMovingAverageParams : IndicatorParams { @@ -54,15 +54,15 @@ struct IndiCustomMovingAverageParams : IndicatorParams { /** * Implements the Custom Moving Average indicator. */ -class Indi_CustomMovingAverage : public Indicator { +class Indi_CustomMovingAverage : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_CustomMovingAverage(IndiCustomMovingAverageParams& _p, IndicatorBase* _indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_CustomMovingAverage(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_CUSTOM_MOVING_AVG, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_CUSTOM_MOVING_AVG, _tf, _shift){}; /** * Returns the indicator's value. diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index 4621be7c2..bf5a19ebd 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -27,7 +27,7 @@ // Includes. #include "../Dict.mqh" #include "../DictObject.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Refs.mqh" #include "../Storage/Objects.h" #include "../Storage/ValueStorage.h" @@ -63,13 +63,14 @@ struct IndiDEIndiMAParams : IndicatorParams { /** * Implements the Moving Average indicator. */ -class Indi_DEMA : public Indicator { +class Indi_DEMA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DEMA, _tf, _shift) {} + Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_DEMA, _tf, _shift) {} /** * Updates the indicator value. diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index cea440264..dbff0f090 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -50,14 +50,14 @@ struct IndiDeMarkerParams : IndicatorParams { /** * Implements the DeMarker indicator. */ -class Indi_DeMarker : public Indicator { +class Indi_DeMarker : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DEMARKER, _tf, _shift) {} + Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_DEMARKER, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index cdf8fbb2e..9fd756862 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Price/Indi_Price.mqh" /** @@ -53,13 +53,14 @@ struct IndiDemoParams : IndicatorParams { /** * Demo/Dummy Indicator. */ -class Indi_Demo : public Indicator { +class Indi_Demo : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Demo(IndiDemoParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DEMO, _tf, _shift){}; + Indi_Demo(IndiDemoParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_DEMO, _tf, _shift){}; /** * Returns the indicator value. diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index 9c60f2207..3f78bdddd 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.price.h" #include "Indi_MA.mqh" @@ -48,15 +48,15 @@ struct IndiDetrendedPriceParams : IndicatorParams { /** * Implements Detrended Price Oscillator. */ -class Indi_DetrendedPrice : public Indicator { +class Indi_DetrendedPrice : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_DetrendedPrice(IndiDetrendedPriceParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_DetrendedPrice(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_DETRENDED_PRICE, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_DETRENDED_PRICE, _tf, _shift){}; /** * Built-in version of AMA. diff --git a/Indicators/Indi_Drawer.mqh b/Indicators/Indi_Drawer.mqh index 3130ea7c6..8825e447e 100644 --- a/Indicators/Indi_Drawer.mqh +++ b/Indicators/Indi_Drawer.mqh @@ -26,7 +26,7 @@ struct IndicatorParams; // Includes. #include "../Action.mqh" #include "../DictStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Redis.mqh" #include "Indi_Drawer.struct.h" #include "Price/Indi_Price.mqh" @@ -34,7 +34,7 @@ struct IndicatorParams; /** * Implements the Relative Strength Index indicator. */ -class Indi_Drawer : public Indicator { +class Indi_Drawer : public IndicatorTickOrCandleSource { Redis redis; public: @@ -42,10 +42,11 @@ class Indi_Drawer : public Indicator { * Class constructor. */ Indi_Drawer(const IndiDrawerParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src), redis(true) { + : IndicatorTickOrCandleSource(_p, _indi_src), redis(true) { Init(); } - Indi_Drawer(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_DRAWER, _tf, _shift), redis(true) { + Indi_Drawer(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_DRAWER, _tf, _shift), redis(true) { Init(); } diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index bc4e5c41a..c9ac3d055 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/Singleton.h" #include "Indi_MA.mqh" #include "Indi_PriceFeeder.mqh" @@ -76,14 +76,15 @@ struct IndiEnvelopesParams : IndicatorParams { /** * Implements the Envelopes indicator. */ -class Indi_Envelopes : public Indicator { +class Indi_Envelopes : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ENVELOPES, _tf, _shift) {} + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_ENVELOPES, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index a752c8938..3c6f6e408 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -32,7 +32,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -65,14 +65,15 @@ struct IndiForceParams : IndicatorParams { /** * Implements the Force Index indicator. */ -class Indi_Force : public Indicator { +class Indi_Force : public IndicatorTickOrCandleSource { protected: public: /** * Class constructor. */ - Indi_Force(IndiForceParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_FORCE, _tf, _shift) {} + Indi_Force(IndiForceParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_FORCE, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index a9d1810ac..a0c69a60c 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -50,14 +50,14 @@ struct IndiFrAIndiMAParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_FrAMA : public Indicator { +class Indi_FrAMA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_FRAMA, _tf, _shift){}; + Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_FRAMA, _tf, _shift){}; /** * Built-in version of FrAMA. diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 832f5d9aa..86d7a37fd 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -48,14 +48,14 @@ struct IndiFractalsParams : IndicatorParams { /** * Implements the Fractals indicator. */ -class Indi_Fractals : public Indicator { +class Indi_Fractals : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Fractals(IndiFractalsParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Fractals(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_FRACTALS, _tf, _shift) {} + Indi_Fractals(IndiFractalsParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Fractals(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_FRACTALS, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index e256b21b7..ff8803c1b 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -28,7 +28,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -103,13 +103,14 @@ struct IndiGatorParams : IndicatorParams { /** * Implements the Gator oscillator. */ -class Indi_Gator : public Indicator { +class Indi_Gator : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Gator(IndiGatorParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Gator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_GATOR, _tf, _shift) {} + Indi_Gator(IndiGatorParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Gator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_GATOR, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 52c15667e..5c2da1599 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -28,7 +28,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Enums. @@ -68,14 +68,15 @@ struct IndiHeikenAshiParams : IndicatorParams { /** * Implements the Heiken-Ashi indicator. */ -class Indi_HeikenAshi : public Indicator { +class Indi_HeikenAshi : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_HeikenAshi(IndiHeikenAshiParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_HeikenAshi(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_HEIKENASHI, _tf, _shift) {} + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_HeikenAshi(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_HEIKENASHI, _tf, _shift) {} /** * Returns value for iHeikenAshi indicator. diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 2b3378c79..a207e884d 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -86,14 +86,14 @@ struct IndiIchimokuParams : IndicatorParams { /** * Implements the Ichimoku Kinko Hyo indicator. */ -class Indi_Ichimoku : public Indicator { +class Indi_Ichimoku : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Ichimoku(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ICHIMOKU, _tf, _shift) {} + Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Ichimoku(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_ICHIMOKU, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index 89913eeb5..5fc584d03 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Market.struct.h" // Defines enumerations. @@ -91,7 +91,7 @@ struct Indi_Killzones_Time : MarketTimeForex { /** * Implements Pivot Detector. */ -class Indi_Killzones : public Indicator { +class Indi_Killzones : public IndicatorTickOrCandleSource { protected: Indi_Killzones_Time ikt; @@ -100,8 +100,9 @@ class Indi_Killzones : public Indicator { * Class constructor. */ Indi_Killzones(IndiKillzonesParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_KILLZONES, _tf, _shift) {} + : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_KILLZONES, _tf, _shift) {} /** * Returns the indicator's value. diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 3cdd2083d..d9a23f29c 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -27,7 +27,7 @@ // Includes. #include "../Dict.mqh" #include "../DictObject.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickSource.h" #include "../Refs.mqh" #include "../Storage/Singleton.h" #include "../Storage/ValueStorage.h" @@ -74,13 +74,13 @@ struct IndiMAParams : IndicatorParams { /** * Implements the Moving Average indicator. */ -class Indi_MA : public Indicator { +class Indi_MA : public IndicatorTickSource { public: /** * Class constructor. */ - Indi_MA(IndiMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MA, _tf, _shift) {} + Indi_MA(IndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_MA, _tf, _shift) {} /** * Returns the indicator value. @@ -665,6 +665,35 @@ class Indi_MA : public Indicator { return _ptr; } + /** + * Returns value storage of given kind. + */ + IValueStorage *GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: + case INDI_VS_TYPE_PRICE_BID: + // We're returning the same buffer for ask and bid price, as target indicator probably won't bother. + return GetValueStorage(0); + default: + // Trying in parent class. + return Indicator::GetSpecificValueStorage(_type); + } + } + + /** + * Checks whether indicator support given value storage type. + */ + bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: + case INDI_VS_TYPE_PRICE_BID: + return true; + default: + // Trying in parent class. + return Indicator::HasSpecificValueStorage(_type); + } + } + /* Getters */ /** diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index 6724dfc2a..2470e2ead 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -59,13 +59,14 @@ struct IndiMACDParams : IndicatorParams { /** * Implements the Moving Averages Convergence/Divergence indicator. */ -class Indi_MACD : public Indicator { +class Indi_MACD : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_MACD(IndiMACDParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MACD, _tf, _shift) {} + Indi_MACD(IndiMACDParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_MACD, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 4a9327585..0427138c0 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -51,13 +51,13 @@ struct IndiMFIParams : IndicatorParams { /** * Implements the Money Flow Index indicator. */ -class Indi_MFI : public Indicator { +class Indi_MFI : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_MFI(IndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MFI, _tf, _shift) {} + Indi_MFI(IndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MFI, _tf, _shift) {} /** * Calculates the Money Flow Index indicator and returns its value. diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 3b4821127..b541f236e 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "Indi_MA.mqh" @@ -50,14 +50,15 @@ struct IndiMassIndexParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_MassIndex : public Indicator { +class Indi_MassIndex : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_MassIndex(IndiMassIndexParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MASS_INDEX, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_MASS_INDEX, _tf, _shift){}; /** * Built-in version of Mass Index. diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 0d461e47c..327588ed2 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -30,7 +30,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Indi_PriceFeeder.mqh" #ifndef __MQL4__ @@ -61,14 +61,14 @@ struct IndiMomentumParams : IndicatorParams { /** * Implements the Momentum indicator. */ -class Indi_Momentum : public Indicator { +class Indi_Momentum : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Momentum(IndiMomentumParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src) {} - Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_MOMENTUM, _tf, _shift) {} + Indi_Momentum(IndiMomentumParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_MOMENTUM, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index b904b3e52..86c6eb44a 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -62,13 +62,13 @@ struct IndiOBVParams : IndicatorParams { /** * Implements the On Balance Volume indicator. */ -class Indi_OBV : public Indicator { +class Indi_OBV : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_OBV(IndiOBVParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_OBV, _tf, _shift) {} + Indi_OBV(IndiOBVParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OBV, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index a6930aab8..7a27cf939 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -58,13 +58,14 @@ struct IndiOsMAParams : IndicatorParams { /** * Implements the Moving Average of Oscillator indicator. */ -class Indi_OsMA : public Indicator { +class Indi_OsMA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_OsMA(IndiOsMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_OSMA, _tf, _shift) {} + Indi_OsMA(IndiOsMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_OSMA, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 6ef493d08..c4c785be6 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -44,13 +44,14 @@ struct IndiPivotParams : IndicatorParams { /** * Implements Pivot Detector. */ -class Indi_Pivot : public Indicator { +class Indi_Pivot : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Pivot(IndiPivotParams& _p, IndicatorBase* _indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PIVOT, _tf, _shift) { + Indi_Pivot(IndiPivotParams& _p, IndicatorBase* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PIVOT, _tf, _shift) { iparams.tf = _tf; }; diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index afcc17ed5..97fbe41d2 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Indi_ZigZag.mqh" // Structs. @@ -45,15 +45,15 @@ struct IndiPriceChannelParams : IndicatorParams { /** * Implements Price Channel indicator. */ -class Indi_PriceChannel : public Indicator { +class Indi_PriceChannel : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_PriceChannel(IndiPriceChannelParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_PriceChannel(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_PRICE_CHANNEL, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_PRICE_CHANNEL, _tf, _shift){}; /** * Returns value for Price Channel indicator. diff --git a/Indicators/Indi_PriceFeeder.mqh b/Indicators/Indi_PriceFeeder.mqh index 459c8e8df..9dfc075ea 100644 --- a/Indicators/Indi_PriceFeeder.mqh +++ b/Indicators/Indi_PriceFeeder.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" // Structs. struct IndiPriceFeederParams : IndicatorParams { @@ -53,17 +53,18 @@ struct IndiPriceFeederParams : IndicatorParams { /** * Price Indicator. */ -class Indi_PriceFeeder : public Indicator { +class Indi_PriceFeeder : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_PriceFeeder(IndiPriceFeederParams& _p, IndicatorBase* _indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_PriceFeeder(const double& _price_data[], int _total = 0) : Indicator(INDI_PRICE_FEEDER) { + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_PriceFeeder(const double& _price_data[], int _total = 0) : IndicatorTickOrCandleSource(INDI_PRICE_FEEDER) { ArrayCopy(iparams.price_data, _price_data); }; - Indi_PriceFeeder(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PRICE_FEEDER, _tf, _shift) {} + Indi_PriceFeeder(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PRICE_FEEDER, _tf, _shift) {} void SetPrices(const double& _price_data[], int _total = 0) { iparams = IndiPriceFeederParams(_price_data, _total); } diff --git a/Indicators/Indi_PriceVolumeTrend.mqh b/Indicators/Indi_PriceVolumeTrend.mqh index 35b40cdc9..9f4899142 100644 --- a/Indicators/Indi_PriceVolumeTrend.mqh +++ b/Indicators/Indi_PriceVolumeTrend.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -45,15 +45,15 @@ struct IndiPriceVolumeTrendParams : IndicatorParams { /** * Implements the Price Volume Trend indicator. */ -class Indi_PriceVolumeTrend : public Indicator { +class Indi_PriceVolumeTrend : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_PriceVolumeTrend(IndiPriceVolumeTrendParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_PriceVolumeTrend(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_PRICE_VOLUME_TREND, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_PRICE_VOLUME_TREND, _tf, _shift){}; /** * Built-in version of Price Volume Trend. diff --git a/Indicators/Indi_RS.mqh b/Indicators/Indi_RS.mqh index 29df1fecb..ef81af539 100644 --- a/Indicators/Indi_RS.mqh +++ b/Indicators/Indi_RS.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "OHLC/Indi_OHLC.mqh" #include "Special/Indi_Math.mqh" @@ -46,15 +46,17 @@ struct IndiRSParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_RS : public Indicator { +class Indi_RS : public IndicatorTickOrCandleSource { DictStruct> imath; public: /** * Class constructor. */ - Indi_RS(IndiRSParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) { Init(); }; - Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_RS, _tf, _shift) { Init(); }; + Indi_RS(IndiRSParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) { Init(); }; + Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RS, _tf, _shift) { + Init(); + }; void Init() { if (iparams.GetDataSourceType() == IDATA_MATH) { diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index 41af38bbe..e8b725b7d 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -22,7 +22,7 @@ // Includes. #include "../DictStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "Indi_Bands.mqh" #include "Indi_CCI.mqh" #include "Indi_Envelopes.mqh" @@ -89,15 +89,15 @@ struct RSIGainLossData { /** * Implements the Relative Strength Index indicator. */ -class Indi_RSI : public Indicator { +class Indi_RSI : public IndicatorTickOrCandleSource { DictStruct aux_data; public: /** * Class constructor. */ - Indi_RSI(IndiRSIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_RSI, _tf, _shift) {} + Indi_RSI(IndiRSIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RSI, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index e7c7d8b39..24c2ac436 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -50,13 +50,13 @@ struct IndiRVIParams : IndicatorParams { /** * Implements the Relative Vigor Index indicator. */ -class Indi_RVI : public Indicator { +class Indi_RVI : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_RVI(const IndiRVIParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_RVI, _tf, _shift) {} + Indi_RVI(const IndiRVIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RVI, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index e6508ddab..2f0d5b061 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.price.h" // Structs. @@ -47,15 +47,15 @@ struct IndiRateOfChangeParams : IndicatorParams { /** * Implements the Rate of Change indicator. */ -class Indi_RateOfChange : public Indicator { +class Indi_RateOfChange : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_RateOfChange(IndiRateOfChangeParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_RateOfChange(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_RATE_OF_CHANGE, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_RATE_OF_CHANGE, _tf, _shift){}; /** * Built-in version of Rate of Change. diff --git a/Indicators/Indi_SAR.mqh b/Indicators/Indi_SAR.mqh index bb7acb110..6f17f2b73 100644 --- a/Indicators/Indi_SAR.mqh +++ b/Indicators/Indi_SAR.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -51,13 +51,13 @@ struct IndiSARParams : IndicatorParams { /** * Implements the Parabolic Stop and Reverse system indicator. */ -class Indi_SAR : public Indicator { +class Indi_SAR : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_SAR(IndiSARParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_SAR, _tf, _shift) {} + Indi_SAR(IndiSARParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SAR, _tf, _shift) {} /** * Returns the indicator value. diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 4dc2327eb..7a6305b77 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -28,7 +28,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickSource.h" #include "../Storage/ObjectsCache.h" #include "Indi_MA.mqh" #include "Indi_PriceFeeder.mqh" @@ -73,13 +73,13 @@ struct IndiStdDevParams : IndicatorParams { /** * Implements the Standard Deviation indicator. */ -class Indi_StdDev : public Indicator { +class Indi_StdDev : public IndicatorTickSource { public: /** * Class constructor. */ - Indi_StdDev(IndiStdDevParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_STDDEV, _tf, _shift) {} + Indi_StdDev(IndiStdDevParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_STDDEV, _tf, _shift) {} /** * Calculates the Standard Deviation indicator and returns its value. diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index 95384d8ae..453208b27 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -62,13 +62,14 @@ struct IndiStochParams : IndicatorParams { /** * Implements the Stochastic Oscillator. */ -class Indi_Stochastic : public Indicator { +class Indi_Stochastic : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Stochastic(IndiStochParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_STOCHASTIC, _tf, _shift) {} + Indi_Stochastic(IndiStochParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_STOCHASTIC, _tf, _shift) {} /** * Calculates the Stochastic Oscillator and returns its value. diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 5ac6bbb6c..5954a9804 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.price.h" #include "Indi_MA.mqh" @@ -50,13 +50,14 @@ struct IndiTEMAParams : IndicatorParams { /** * Implements the Triple Exponential Moving Average indicator. */ -class Indi_TEMA : public Indicator { +class Indi_TEMA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_TEMA(IndiTEMAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_TEMA, _tf, _shift){}; + Indi_TEMA(IndiTEMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_TEMA, _tf, _shift){}; /** * Built-in version of TEMA. diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index e480701b7..86caabb0d 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.price.h" #include "Indi_MA.mqh" @@ -49,13 +49,14 @@ struct IndiTRIXParams : IndicatorParams { /** * Implements the Triple Exponential Average indicator. */ -class Indi_TRIX : public Indicator { +class Indi_TRIX : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_TRIX(IndiTRIXParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_TRIX, _tf, _shift){}; + Indi_TRIX(IndiTRIXParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_TRIX, _tf, _shift){}; /** * Built-in version of TriX. diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index ff63857d4..98a7f9e1f 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "Indi_ATR.mqh" #include "Indi_MA.mqh" @@ -62,15 +62,15 @@ struct IndiUltimateOscillatorParams : IndicatorParams { /** * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ -class Indi_UltimateOscillator : public Indicator { +class Indi_UltimateOscillator : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_UltimateOscillator(IndiUltimateOscillatorParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_UltimateOscillator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : Indicator(INDI_ULTIMATE_OSCILLATOR, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_ULTIMATE_OSCILLATOR, _tf, _shift){}; /** * Built-in version of Ultimate Oscillator. diff --git a/Indicators/Indi_VIDYA.mqh b/Indicators/Indi_VIDYA.mqh index 8499e9b32..4e98a6254 100644 --- a/Indicators/Indi_VIDYA.mqh +++ b/Indicators/Indi_VIDYA.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.price.h" // Structs. @@ -53,13 +53,14 @@ struct IndiVIDYAParams : IndicatorParams { /** * Implements the Variable Index Dynamic Average indicator. */ -class Indi_VIDYA : public Indicator { +class Indi_VIDYA : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_VIDYA(IndiVIDYAParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_VIDYA, _tf, _shift){}; + Indi_VIDYA(IndiVIDYAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_VIDYA, _tf, _shift){}; /** * Built-in version of iVIDyA. diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index 439e009fe..cacf2861c 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -47,13 +47,14 @@ struct IndiVROCParams : IndicatorParams { /** * Implements the Volume Rate of Change indicator. */ -class Indi_VROC : public Indicator { +class Indi_VROC : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_VROC(IndiVROCParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_VROC, _tf, _shift){}; + Indi_VROC(IndiVROCParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; /** * Built-in version of VROC. diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 1f5333b93..c46671424 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -46,13 +46,14 @@ struct IndiVolumesParams : IndicatorParams { /** * Implements the Volumes indicator. */ -class Indi_Volumes : public Indicator { +class Indi_Volumes : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Volumes(IndiVolumesParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_VOLUMES, _tf, _shift){}; + Indi_Volumes(IndiVolumesParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_VOLUMES, _tf, _shift){}; /** * Built-in version of Volumes. diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index 1504f2ecf..98c59474c 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #ifndef __MQL4__ // Defines global functions (for MQL4 backward compability). @@ -50,13 +50,13 @@ struct IndiWPRParams : IndicatorParams { /** * Implements the Larry Williams' Percent Range. */ -class Indi_WPR : public Indicator { +class Indi_WPR : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_WPR(IndiWPRParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_WPR, _tf, _shift) {} + Indi_WPR(IndiWPRParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WPR, _tf, _shift) {} /** * Calculates the Larry Williams' Percent Range and returns its value. diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index cf1a6513f..7e2bf94e4 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Structs. @@ -42,14 +42,15 @@ struct IndiWilliamsADParams : IndicatorParams { /** * Implements the Volume Rate of Change indicator. */ -class Indi_WilliamsAD : public Indicator { +class Indi_WilliamsAD : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_WILLIAMS_AD, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_WILLIAMS_AD, _tf, _shift){}; /** * Built-in version of Williams' AD. diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 912eb8eff..4803a45e6 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -21,7 +21,7 @@ */ // Includes. -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" // Enums. @@ -58,13 +58,14 @@ enum EnSearchMode { /** * Implements ZigZag indicator. */ -class Indi_ZigZag : public Indicator { +class Indi_ZigZag : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_ZigZag(IndiZigZagParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} - Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_ZIGZAG, _tf, _shift) {} + Indi_ZigZag(IndiZigZagParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_ZIGZAG, _tf, _shift) {} /** * Returns value for ZigZag indicator. diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index af74e2f50..6e8cf6d9a 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -22,7 +22,7 @@ // Includes. #include "../BufferStruct.mqh" -#include "../Indicator.mqh" +#include "../Indicator/IndicatorTickOrCandleSource.h" #include "../Storage/ValueStorage.all.h" #include "Indi_ZigZag.mqh" @@ -52,14 +52,15 @@ struct IndiZigZagColorParams : IndicatorParams { /** * Implements the Volume Rate of Change indicator. */ -class Indi_ZigZagColor : public Indicator { +class Indi_ZigZagColor : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ Indi_ZigZagColor(IndiZigZagColorParams &_p, IndicatorBase *_indi_src = NULL) - : Indicator(_p, _indi_src){}; - Indi_ZigZagColor(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_VROC, _tf, _shift){}; + : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ZigZagColor(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; /** * Returns value for ZigZag Color indicator. diff --git a/Indicators/OHLC/Indi_OHLC.mqh b/Indicators/OHLC/Indi_OHLC.mqh index c6c3d39ef..c7f9cc25c 100644 --- a/Indicators/OHLC/Indi_OHLC.mqh +++ b/Indicators/OHLC/Indi_OHLC.mqh @@ -22,7 +22,7 @@ // Includes. #include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" #include "../../Storage/Objects.h" // Enums. @@ -49,13 +49,14 @@ struct IndiOHLCParams : IndicatorParams { /** * OHLC Indicator. */ -class Indi_OHLC : public Indicator { +class Indi_OHLC : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_OHLC(IndiOHLCParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_OHLC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PRICE, _tf, _shift){}; + Indi_OHLC(IndiOHLCParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_OHLC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; /** * Returns the indicator's value. diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index 89b0f7279..b0cbcc6d3 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -22,7 +22,7 @@ // Includes. #include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" #include "../../Storage/Objects.h" // Structs. @@ -46,13 +46,14 @@ struct PriceIndiParams : IndicatorParams { /** * Price Indicator. */ -class Indi_Price : public Indicator { +class Indi_Price : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Price(PriceIndiParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Price(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_PRICE, _tf, _shift){}; + Indi_Price(PriceIndiParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Price(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; /** * Checks whether indicator has a valid value for a given shift. @@ -86,4 +87,54 @@ class Indi_Price : public Indicator { } return _indi_price; } + + /** + * Returns value storage of given kind. + */ + IValueStorage *GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + // Returning Price indicator which provides applied price in the only buffer #0. + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: // Tick. + case INDI_VS_TYPE_PRICE_BID: // Tick. + return GetCached(GetSymbol(), iparams.GetAppliedPrice(), GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_OPEN: // Candle. + return GetCached(GetSymbol(), PRICE_OPEN, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_HIGH: // Candle. + return GetCached(GetSymbol(), PRICE_HIGH, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_LOW: // Candle. + return GetCached(GetSymbol(), PRICE_LOW, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_CLOSE: // Candle. + return GetCached(GetSymbol(), PRICE_CLOSE, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_MEDIAN: // Candle. + return GetCached(GetSymbol(), PRICE_MEDIAN, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_TYPICAL: // Candle. + return GetCached(GetSymbol(), PRICE_TYPICAL, GetTf(), iparams.GetShift()).GetValueStorage(0); + case INDI_VS_TYPE_PRICE_WEIGHTED: // Candle. + return GetCached(GetSymbol(), PRICE_WEIGHTED, GetTf(), iparams.GetShift()).GetValueStorage(0); + default: + // Trying in parent class. + return Indicator::GetSpecificValueStorage(_type); + } + } + + /** + * Checks whether indicator support given value storage type. + */ + bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: // Tick. + case INDI_VS_TYPE_PRICE_BID: // Tick. + case INDI_VS_TYPE_PRICE_OPEN: // Candle. + case INDI_VS_TYPE_PRICE_HIGH: // Candle. + case INDI_VS_TYPE_PRICE_LOW: // Candle. + case INDI_VS_TYPE_PRICE_CLOSE: // Candle. + case INDI_VS_TYPE_PRICE_MEDIAN: // Candle. + case INDI_VS_TYPE_PRICE_TYPICAL: // Candle. + case INDI_VS_TYPE_PRICE_WEIGHTED: // Candle. + return true; + default: + // Trying in parent class. + return Indicator::HasSpecificValueStorage(_type); + } + } }; diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index e1c991916..eaacecca5 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -22,7 +22,7 @@ // Includes. #include "../../BufferStruct.mqh" -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" #include "../../Math.enum.h" enum ENUM_MATH_OP_MODE { MATH_OP_MODE_BUILTIN, MATH_OP_MODE_CUSTOM_FUNCTION }; @@ -82,13 +82,14 @@ struct IndiMathParams : IndicatorParams { /** * Implements the Volume Rate of Change indicator. */ -class Indi_Math : public Indicator { +class Indi_Math : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Math(IndiMathParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src){}; - Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : Indicator(INDI_SPECIAL_MATH, _tf, _shift){}; + Indi_Math(IndiMathParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_SPECIAL_MATH, _tf, _shift){}; /** * Returns the indicator's value. diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 918c3e734..c23ca7cf5 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -334,7 +334,7 @@ bool InitIndicators() { stddev_params_on_ma_sma.SetDraw(true, 1); Ref indi_stddev_on_ma_sma = new Indi_StdDev(stddev_params_on_ma_sma); - indi_stddev_on_ma_sma.Ptr().SetDataSource(indi_ma_sma_for_stddev.Ptr(), 0); + indi_stddev_on_ma_sma.Ptr().SetDataSource(indi_ma_sma_for_stddev.Ptr()); indis.Push(indi_stddev_on_ma_sma.Ptr()); // Standard Deviation (StdDev) in SMA mode over Price. From c5be80f23f5fc475f2875ebb18b806bd5c232e6a Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 29 Dec 2021 19:03:22 +0100 Subject: [PATCH 45/81] WIP. Closer to the end. Now we need to find a way to feed indicator with ticks from data source, e.g., to feed AMA from Tick/Candle indicator when they ticks and provides new ask/bid prices. --- Chart.enum.h | 5 ++ Indicator/IndicatorCandle.h | 1 + Indicator/IndicatorTick.h | 46 +++++++++++++-- Indicator/IndicatorTickOrCandleSource.h | 9 --- Indicator/IndicatorTickSource.h | 2 +- Indicator/tests/classes/IndicatorTickReal.h | 6 +- IndicatorBase.h | 62 ++++++++++++++++++++- Indicators/Indi_AMA.mqh | 12 +++- Storage/ValueStorage.h | 10 +++- tests/IndicatorsTest.mq5 | 5 +- 10 files changed, 135 insertions(+), 23 deletions(-) diff --git a/Chart.enum.h b/Chart.enum.h index e7e68247c..5835ba3da 100644 --- a/Chart.enum.h +++ b/Chart.enum.h @@ -43,9 +43,14 @@ enum ENUM_APPLIED_PRICE { PRICE_MEDIAN, // Median price (H+L)/2 PRICE_TYPICAL, // Typical price, (H+L+C)/3 PRICE_WEIGHTED, // Weighted close price (H+L+C+C)/4 + FINAL_APPLIED_PRICE_ENTRY }; #endif +// Additional modes for applied price. +#define PRICE_ASK ((ENUM_APPLIED_PRICE)128) +#define PRICE_BID ((ENUM_APPLIED_PRICE)129) + // Defines enumeration for chart parameters. enum ENUM_CHART_PARAM { CHART_PARAM_NONE = 0, // None diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 29c4fbd2e..6d5711a31 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -33,6 +33,7 @@ #include "../Buffer/BufferCandle.h" #include "../Indicator.mqh" +// Indicator modes. enum ENUM_INDI_CANDLE_MODE { INDI_CANDLE_MODE_PRICE_OPEN, INDI_CANDLE_MODE_PRICE_HIGH, diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index c5ad92d86..b29a8070b 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -33,11 +33,18 @@ #include "../Buffer/BufferTick.h" #include "../IndicatorBase.h" +// Indicator modes. +enum ENUM_INDI_TICK_MODE { + INDI_TICK_MODE_PRICE_ASK, + INDI_TICK_MODE_PRICE_BID, + FINAL_INDI_TICK_MODE_ENTRY, +}; + /** * Class to deal with tick indicators. */ template -class IndicatorTick : public IndicatorBase { +class IndicatorTick : public Indicator { protected: BufferTick itdata; TS itparams; @@ -63,21 +70,50 @@ class IndicatorTick : public IndicatorBase { /** * Class constructor. */ - IndicatorTick(const TS& _itparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) { + IndicatorTick(const TS& _itparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + : Indicator(_itparams, _indi_src, _indi_mode) { itparams = _itparams; if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); } Init(); } - IndicatorTick(ENUM_INDICATOR_TYPE _itype, string _symbol, int _shift = 0, string _name = "") { - itparams.SetIndicatorType(_itype); - itparams.SetShift(_shift); + IndicatorTick(ENUM_INDICATOR_TYPE _itype = INDI_CANDLE, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, + string _name = "") + : Indicator(_itype, _tf, _shift, _name) { Init(); } /* Virtual method implementations */ + /** + * Returns value storage of given kind. + */ + IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: + return GetValueStorage(INDI_TICK_MODE_PRICE_ASK); + case INDI_VS_TYPE_PRICE_BID: + return GetValueStorage(INDI_TICK_MODE_PRICE_BID); + default: + // Trying in parent class. + return Indicator::GetSpecificValueStorage(_type); + } + } + + /** + * Checks whether indicator support given value storage type. + */ + virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { + switch (_type) { + case INDI_VS_TYPE_PRICE_ASK: + case INDI_VS_TYPE_PRICE_BID: + return true; + } + + return Indicator::HasSpecificValueStorage(_type); + } + /** * Sends historic entries to listening indicators. May be overriden. */ diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h index b7bc25265..a4e0f902f 100644 --- a/Indicator/IndicatorTickOrCandleSource.h +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -60,13 +60,4 @@ class IndicatorTickOrCandleSource : public Indicator { // @todo Make use of this method. return true; } - - /** - * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on - * some data source. - */ - IndicatorBase* OnDataSourceRequest() override { - // Defaulting to platform ticks. - return new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal"); - } }; diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h index 58800c0b8..2780498f9 100644 --- a/Indicator/IndicatorTickSource.h +++ b/Indicator/IndicatorTickSource.h @@ -123,6 +123,6 @@ class IndicatorTickSource : public Indicator { */ IndicatorBase* OnDataSourceRequest() override { // Defaulting to platform ticks. - return new IndicatorTickReal(GetSymbol(), GetTf(), "AMA on IndicatorTickReal"); + return new IndicatorTickReal(GetTf(), 0, "AMA on IndicatorTickReal"); } }; diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index a654c4da8..977c5cc48 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -41,10 +41,8 @@ struct IndicatorTickRealParams : IndicatorParams { // Real tick-based indicator. class IndicatorTickReal : public IndicatorTick { public: - IndicatorTickReal(string _symbol, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { - SetSymbol(_symbol); - } + IndicatorTickReal(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} string GetName() override { return "IndicatorTickReal"; } diff --git a/IndicatorBase.h b/IndicatorBase.h index f0b0e4677..2c734290d 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -303,7 +303,37 @@ class IndicatorBase : public Chart { * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on * some data source. */ - virtual IndicatorBase* OnDataSourceRequest() { return NULL; } + virtual IndicatorBase* OnDataSourceRequest() { + Print("In order to use IDATA_INDICATOR mode for indicator ", GetFullName(), + " without explicitly selecting an indicator, ", GetFullName(), + " must override OnDataSourceRequest() method and return new instance of data source to be used by default."); + DebugBreak(); + return NULL; + } + + /** + * Creates default, tick based indicator for given applied price. + */ + IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) { + // Returning real candle indicator. Thus way we can use SetAppliedPrice() and select Ask or Bid price. + switch (_applied_price) { + case PRICE_ASK: + case PRICE_BID: + return new IndicatorTickReal(GetTf()); + case PRICE_OPEN: + case PRICE_HIGH: + case PRICE_LOW: + case PRICE_CLOSE: + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + return new IndicatorTfDummy(GetTf()); + } + + Print("Passed wrong value for applied price for ", GetFullName(), " indicator!"); + DebugBreak(); + return NULL; + } /* Getters */ @@ -464,6 +494,10 @@ class IndicatorBase : public Chart { virtual IValueStorage* GetSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { switch (_ap) { + case PRICE_ASK: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); + case PRICE_BID: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); case PRICE_OPEN: return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); case PRICE_HIGH: @@ -484,6 +518,32 @@ class IndicatorBase : public Chart { } } + virtual bool HasSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { + switch (_ap) { + case PRICE_ASK: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); + case PRICE_BID: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); + case PRICE_OPEN: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + case PRICE_HIGH: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + case PRICE_LOW: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + case PRICE_CLOSE: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + default: + Print("Error: Invalid applied price " + EnumToString(_ap) + + ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " + "IndicatorBase::HasSpecificAppliedPriceValueStorage()!"); + DebugBreak(); + return false; + } + } + /** * Checks whether indicator support given value storage type. */ diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 206c2cb77..819ee824f 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -23,6 +23,7 @@ // Includes. #include "../BufferStruct.mqh" #include "../Indicator/IndicatorTickOrCandleSource.h" +#include "../Indicator/tests/classes/IndicatorTfDummy.h" #include "../Storage/ValueStorage.h" #include "../Storage/ValueStorage.price.h" #include "Price/Indi_Price.mqh" @@ -244,7 +245,16 @@ class Indi_AMA : public IndicatorTickOrCandleSource { /** * Called when data source emits new entry (historic or future one). */ - void OnDataSourceEntry(IndicatorDataEntry &entry) override { Print("New entry for AMA!"); }; + void OnDataSourceEntry(IndicatorDataEntry &entry) override { + // Just to be able to make a breakpoint here. + int x = 4; + }; + + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + virtual IndicatorBase *OnDataSourceRequest() { return DataSourceRequestReturnDefault(GetAppliedPrice()); } /* Getters */ diff --git a/Storage/ValueStorage.h b/Storage/ValueStorage.h index ea2730712..36efe0049 100644 --- a/Storage/ValueStorage.h +++ b/Storage/ValueStorage.h @@ -92,7 +92,15 @@ enum ENUM_IPEAK { IPEAK_LOWEST, IPEAK_HIGHEST }; INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) #define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC(INDI, SYMBOL, TF, APPLIED_PRICE, KEY) \ - ValueStorage *_price = INDI.GetSpecificAppliedPriceValueStorage(APPLIED_PRICE); \ + ValueStorage *_price; \ + if (_indi.HasSpecificAppliedPriceValueStorage(APPLIED_PRICE)) { \ + _price = INDI.GetSpecificAppliedPriceValueStorage(APPLIED_PRICE); \ + } else { \ + Print("Source indicator ", INDI.GetFullName(), \ + " cannot be used as it doesn't provide a single buffer to be used by target indicator!"); \ + DebugBreak(); \ + } \ + \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) #define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(INDI, SYMBOL, TF, KEY) \ diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index c23ca7cf5..0120c35ea 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -423,7 +423,10 @@ bool InitIndicators() { // AMA. IndiAMAParams ama_params(); ama_params.SetDataSourceType(IDATA_INDICATOR); - indis.Push(new Indi_AMA(ama_params)); + Indi_AMA* _indi_ama = new Indi_AMA(ama_params); + // AMA will automatically sets its data source to Tick or Candle indicator by value of APPLIED_PRICE. + _indi_ama.SetAppliedPrice(PRICE_ASK); + indis.Push(_indi_ama); // Original AMA. IndiAMAParams ama_params_orig(); From 88d0a7c3779b83c93590812998fe4dbb495c37b7 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 30 Dec 2021 20:57:42 +0100 Subject: [PATCH 46/81] WIP. Now we need to find a way to make BufferTick to provide continuous ticks, instead of random ones collected in DictStruct. --- Buffer/BufferTick.h | 77 ++++++++++++++++++++++++- Indicator/IndicatorTick.h | 6 +- Indicator/IndicatorTickOrCandleSource.h | 7 +++ IndicatorBase.h | 6 +- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/Buffer/BufferTick.h b/Buffer/BufferTick.h index 70965dcfe..bc8f2fa4e 100644 --- a/Buffer/BufferTick.h +++ b/Buffer/BufferTick.h @@ -26,14 +26,51 @@ // Includes. #include "../BufferStruct.mqh" +#include "../Storage/IValueStorage.h" #include "../Tick.struct.h" +template +class BufferTickValueStorage : ValueStorage { + // Poiner to buffer to take tick from. + BufferTick *buffer_tick; + + // PRICE_ASK or PRICE_BID. + int applied_price; + + public: + /** + * Constructor. + */ + BufferTickValueStorage(BufferTick *_buffer_tick, int _applied_price) + : buffer_tick(_buffer_tick), applied_price(_applied_price) {} + + /** + * Fetches value from a given shift. Takes into consideration as-series flag. + */ + TV Fetch(int _shift) override { + Print("BufferTickValueStorage: Fetching " + (applied_price == PRICE_ASK ? "Ask" : "Bid") + " price from shift ", + _shift); + return 0; + } + + /** + * Returns number of values available to fetch (size of the values buffer). + */ + int Size() const override { return (int)buffer_tick.Size(); } +}; + /** * Class to store struct data. */ template class BufferTick : public BufferStruct> { protected: + // Ask prices ValueStorage proxy. + BufferTickValueStorage *_vs_ask; + + // Bid prices ValueStorage proxy. + BufferTickValueStorage *_vs_bid; + protected: /* Protected methods */ @@ -42,7 +79,11 @@ class BufferTick : public BufferStruct> { * * Called on constructor. */ - void Init() { SetOverflowListener(BufferTickOverflowListener, 10); } + void Init() { + _vs_ask = NULL; + _vs_bid = NULL; + SetOverflowListener(BufferTickOverflowListener, 10); + } public: /* Constructors */ @@ -51,11 +92,43 @@ class BufferTick : public BufferStruct> { * Constructor. */ BufferTick() { Init(); } - BufferTick(BufferTick& _right) { + BufferTick(BufferTick &_right) { THIS_REF = _right; Init(); } + /** + * Destructor. + */ + ~BufferTick() { + if (_vs_ask != NULL) { + delete _vs_ask; + } + if (_vs_bid != NULL) { + delete _vs_bid; + } + } + + /** + * Returns Ask prices ValueStorage proxy. + */ + BufferTickValueStorage *GetAskValueStorage() { + if (_vs_ask == NULL) { + _vs_ask = new BufferTickValueStorage(THIS_PTR, PRICE_ASK); + } + return _vs_ask; + } + + /** + * Returns Bid prices ValueStorage proxy. + */ + BufferTickValueStorage *GetBidValueStorage() { + if (_vs_bid == NULL) { + _vs_bid = new BufferTickValueStorage(THIS_PTR, PRICE_BID); + } + return _vs_bid; + } + /* Grouping methods */ /** diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index b29a8070b..34c6564a9 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -84,17 +84,15 @@ class IndicatorTick : public Indicator { Init(); } - /* Virtual method implementations */ - /** * Returns value storage of given kind. */ IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) override { switch (_type) { case INDI_VS_TYPE_PRICE_ASK: - return GetValueStorage(INDI_TICK_MODE_PRICE_ASK); + return (IValueStorage*)itdata.GetAskValueStorage(); case INDI_VS_TYPE_PRICE_BID: - return GetValueStorage(INDI_TICK_MODE_PRICE_BID); + return (IValueStorage*)itdata.GetBidValueStorage(); default: // Trying in parent class. return Indicator::GetSpecificValueStorage(_type); diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h index a4e0f902f..89cebebe4 100644 --- a/Indicator/IndicatorTickOrCandleSource.h +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -60,4 +60,11 @@ class IndicatorTickOrCandleSource : public Indicator { // @todo Make use of this method. return true; } + + /** + * Called when data source emits new entry (historic or future one). + */ + void OnDataSourceEntry(IndicatorDataEntry& entry) override{ + // We do nothing. + }; }; diff --git a/IndicatorBase.h b/IndicatorBase.h index 2c734290d..a57ff5bcd 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -604,9 +604,6 @@ class IndicatorBase : public Chart { last_tick_time = _current_time; - // Overridable OnTick() method. - OnTick(); - // Checking and potentially initializing new data source. if (HasDataSource(true) != NULL) { // Ticking data source if not yet ticked. @@ -617,6 +614,9 @@ class IndicatorBase : public Chart { for (DictStructIterator> iter = indicators.Begin(); iter.IsValid(); ++iter) { iter.Value().Ptr().Tick(); } + + // Overridable OnTick() method. + OnTick(); } virtual void OnTick() {} From c2a87cde54a57ccd48d181b7882403de3b491947 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 4 Jan 2022 16:11:48 +0100 Subject: [PATCH 47/81] AS-IS. --- Indicator.enum.h | 8 +++++++ Indicator.mqh | 13 +++++++++++ Indicator/IndicatorCandle.h | 2 ++ Indicator/IndicatorTick.h | 5 ++++ IndicatorBase.h | 46 +++++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Indicator.enum.h b/Indicator.enum.h index 563282745..872c6ceb1 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -248,3 +248,11 @@ enum ENUM_INDI_VS_TYPE { INDI_VS_TYPE_PRICE_BID, // Tick. INDI_VS_TYPE_PRICE_ASK, // Tick. }; + +// Indicator flags. +enum ENUM_INDI_FLAGS { + INDI_FLAG_INDEXABLE_BY_SHIFT, // Indicator supports indexation by shift. + INDI_FLAG_INDEXABLE_BY_TIMESTAMP, // Indicator supports indexation by shift. + INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT, // Source indicator must be indexable by shift. + INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_TIMESTAMP // Source indicator must be indexable by timestamp. +}; \ No newline at end of file diff --git a/Indicator.mqh b/Indicator.mqh index 8687a702c..47089083c 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -981,6 +981,19 @@ class Indicator : public IndicatorBase { * Sets indicator data source. */ void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { + if (indi_src.IsSet()) { + if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT) && !bool(_indi.flags | INDI_FLAG_INDEXABLE_BY_SHIFT)) { + Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), ", because source indicator isn't indexable by shift!"); + DebugBreak(); + return; + } + if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_TIMESTAMP) && !bool(_indi.flags | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { + Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), ", because source indicator isn't indexable by timestamp!"); + DebugBreak(); + return; + } + } + if (indi_src.IsSet() && indi_src.Ptr() != _indi) { indi_src.Ptr().RemoveListener(THIS_PTR); } diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 6d5711a31..0fffc48ae 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -62,6 +62,8 @@ class IndicatorCandle : public Indicator { * Called on constructor. */ void Init() { + // Along with indexing by shift, we can also index via timestamp! + flags |= INDI_FLAG_INDEXABLE_BY_TIMESTAMP; icdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); icdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); iparams.SetMaxModes(4); diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 34c6564a9..0b7de9d52 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -58,6 +58,11 @@ class IndicatorTick : public Indicator { * Called on constructor. */ void Init() { + // We can't index by shift. + flags &= ~INDI_FLAG_INDEXABLE_BY_SHIFT; + // We can only index via timestamp. + flags |= INDI_FLAG_INDEXABLE_BY_TIMESTAMP; + itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); itdata.SetOverflowListener(IndicatorTickOverflowListener, 10); // Ask and Bid price. diff --git a/IndicatorBase.h b/IndicatorBase.h index a57ff5bcd..71d0e5950 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -72,6 +72,7 @@ class IndicatorBase : public Chart { IndicatorCalculateCache cache; ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. long last_tick_time; // Time of the last Tick() call. + int flags; // Flags such as INDI_FLAG_INDEXABLE_BY_SHIFT. public: /* Indicator enumerations */ @@ -92,6 +93,8 @@ class IndicatorBase : public Chart { * Class constructor. */ IndicatorBase(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) : indi_src(NULL), Chart(_tf, _symbol) { + // By default, indicator is indexable only by shift and data source must be also indexable by shift. + flags = INDI_FLAG_INDEXABLE_BY_SHIFT | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT; calc_start_bar = 0; is_fed = false; indi_src = NULL; @@ -102,6 +105,8 @@ class IndicatorBase : public Chart { * Class constructor. */ IndicatorBase(ENUM_TIMEFRAMES_INDEX _tfi, string _symbol = NULL) : Chart(_tfi, _symbol) { + // By default, indicator is indexable only by shift and data source must be also indexable by shift. + flags = INDI_FLAG_INDEXABLE_BY_SHIFT | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT; calc_start_bar = 0; is_fed = false; indi_src = NULL; @@ -124,11 +129,34 @@ class IndicatorBase : public Chart { /* Operator overloading methods */ /** - * Access indicator entry data using [] operator. + * Access indicator entry data using [] operator via shift. */ - // IndicatorDataEntry operator[](datetime _dt) { return GetEntry(_dt); } - IndicatorDataEntry operator[](int _index) { return GetEntry(_index); } - IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry(_index); } + IndicatorDataEntry operator[](int _index) { + if (!bool(flags | INDI_FLAG_INDEXABLE_BY_SHIFT)) { + Print(GetFullName(), " is not indexable by shift!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; + } + return GetEntry(_index); + } + + /** + * Access indicator entry data using [] operator via datetime. + */ + IndicatorDataEntry operator[](datetime _dt) { + if (!bool(flags | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { + Print(GetFullName(), " is not indexable by timestamp!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; + } + return GetEntry(_dt); + } + + IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { + return GetEntry((int)_index); + } /* Buffer methods */ @@ -630,6 +658,16 @@ class IndicatorBase : public Chart { */ virtual IndicatorDataEntry GetEntry(int _index = 0) = NULL; + /** + * Returns the indicator's struct value. + */ + virtual IndicatorDataEntry GetEntry(datetime _dt) { + Print(GetFullName(), " must implement IndicatorDataEntry IndicatorBase::GetEntry(datetime _dt) in order to use GetEntry(datetime _dt) or _indi[datetime] subscript operator!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; + } + /** * Alters indicator's struct value. * From 435f1d1a0af2e26b368373d85cec6957650b5691 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 5 Jan 2022 14:49:55 +0100 Subject: [PATCH 48/81] WIP. IndicatorsTest ready for testing! --- Buffer/BufferTick.h | 1 + Indicator.enum.h | 8 +-- Indicator.mqh | 14 +++-- Indicator/IndicatorTick.h | 4 +- Indicator/IndicatorTickOrCandleSource.h | 29 +++++++++ Indicator/IndicatorTickSource.h | 9 --- Indicator/tests/IndicatorTf.test.mq5 | 2 +- Indicator/tests/IndicatorTick.test.mq5 | 41 +----------- Indicator/tests/classes/IndicatorTickDummy.h | 66 ++++++++++++++++---- IndicatorBase.h | 35 ++++------- Indicators/Indi_BWMFI.mqh | 2 +- Indicators/Tick/Indi_TickMt.mqh | 3 +- Indicators/Tick/tests/Indi_TickMt.test.mq5 | 2 +- Storage/ValueStorage.h | 21 ++++--- tests/IndicatorsTest.mq5 | 5 +- 15 files changed, 132 insertions(+), 110 deletions(-) diff --git a/Buffer/BufferTick.h b/Buffer/BufferTick.h index bc8f2fa4e..d3eb35dab 100644 --- a/Buffer/BufferTick.h +++ b/Buffer/BufferTick.h @@ -26,6 +26,7 @@ // Includes. #include "../BufferStruct.mqh" +#include "../Chart.enum.h" #include "../Storage/IValueStorage.h" #include "../Tick.struct.h" diff --git a/Indicator.enum.h b/Indicator.enum.h index 872c6ceb1..8bf58e7b1 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -251,8 +251,8 @@ enum ENUM_INDI_VS_TYPE { // Indicator flags. enum ENUM_INDI_FLAGS { - INDI_FLAG_INDEXABLE_BY_SHIFT, // Indicator supports indexation by shift. - INDI_FLAG_INDEXABLE_BY_TIMESTAMP, // Indicator supports indexation by shift. - INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT, // Source indicator must be indexable by shift. + INDI_FLAG_INDEXABLE_BY_SHIFT, // Indicator supports indexation by shift. + INDI_FLAG_INDEXABLE_BY_TIMESTAMP, // Indicator supports indexation by shift. + INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT, // Source indicator must be indexable by shift. INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_TIMESTAMP // Source indicator must be indexable by timestamp. -}; \ No newline at end of file +}; diff --git a/Indicator.mqh b/Indicator.mqh index 47089083c..dcba18a65 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -982,18 +982,22 @@ class Indicator : public IndicatorBase { */ void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { if (indi_src.IsSet()) { - if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT) && !bool(_indi.flags | INDI_FLAG_INDEXABLE_BY_SHIFT)) { - Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), ", because source indicator isn't indexable by shift!"); + if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT) && + !bool(_indi.GetFlags() | INDI_FLAG_INDEXABLE_BY_SHIFT)) { + Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), + ", because source indicator isn't indexable by shift!"); DebugBreak(); return; } - if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_TIMESTAMP) && !bool(_indi.flags | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { - Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), ", because source indicator isn't indexable by timestamp!"); + if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_TIMESTAMP) && + !bool(_indi.GetFlags() | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { + Print(GetFullName(), ": Cannot set data source to ", _indi.GetFullName(), + ", because source indicator isn't indexable by timestamp!"); DebugBreak(); return; } } - + if (indi_src.IsSet() && indi_src.Ptr() != _indi) { indi_src.Ptr().RemoveListener(THIS_PTR); } diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index 0b7de9d52..e654dde70 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -31,7 +31,7 @@ // Includes. #include "../Buffer/BufferTick.h" -#include "../IndicatorBase.h" +#include "../Indicator.mqh" // Indicator modes. enum ENUM_INDI_TICK_MODE { @@ -62,7 +62,7 @@ class IndicatorTick : public Indicator { flags &= ~INDI_FLAG_INDEXABLE_BY_SHIFT; // We can only index via timestamp. flags |= INDI_FLAG_INDEXABLE_BY_TIMESTAMP; - + itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); itdata.SetOverflowListener(IndicatorTickOverflowListener, 10); // Ask and Bid price. diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h index 89cebebe4..45fce1acd 100644 --- a/Indicator/IndicatorTickOrCandleSource.h +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -27,6 +27,7 @@ // Includes. #include "../Indicator.mqh" +#include "tests/classes/IndicatorTfDummy.h" #include "tests/classes/IndicatorTickReal.h" /** @@ -67,4 +68,32 @@ class IndicatorTickOrCandleSource : public Indicator { void OnDataSourceEntry(IndicatorDataEntry& entry) override{ // We do nothing. }; + + /** + * Creates default, tick based indicator for given applied price. + */ + IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) override { + // Returning real candle indicator. Thus way we can use SetAppliedPrice() and select Ask or Bid price. + IndicatorBase* _indi; + + switch (_applied_price) { + case PRICE_ASK: + case PRICE_BID: + case PRICE_OPEN: + case PRICE_HIGH: + case PRICE_LOW: + case PRICE_CLOSE: + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + // @todo ASK/BID should return Tick indicator. Other APs should return Candle-over-Tick indicator. + _indi = new IndicatorTfDummy(GetTf()); + _indi.SetDataSource(new IndicatorTickReal(GetTf())); + return _indi; + } + + Print("Passed wrong value for applied price for ", GetFullName(), " indicator!"); + DebugBreak(); + return NULL; + } }; diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h index 2780498f9..6e1734f4c 100644 --- a/Indicator/IndicatorTickSource.h +++ b/Indicator/IndicatorTickSource.h @@ -116,13 +116,4 @@ class IndicatorTickSource : public Indicator { // @todo Make use of this method. return true; } - - /** - * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on - * some data source. - */ - IndicatorBase* OnDataSourceRequest() override { - // Defaulting to platform ticks. - return new IndicatorTickReal(GetTf(), 0, "AMA on IndicatorTickReal"); - } }; diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 739855fae..71385aecd 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -48,7 +48,7 @@ Ref indi_ama_orig_sim; * Implements OnInit(). */ int OnInit() { - indicators.Add(indi_tick = new IndicatorTickReal(_Symbol)); + indicators.Add(indi_tick = new IndicatorTickReal(PERIOD_CURRENT)); // 1-second candles. // indicators.Add(indi_tf = new IndicatorTfDummy(1)); diff --git a/Indicator/tests/IndicatorTick.test.mq5 b/Indicator/tests/IndicatorTick.test.mq5 index 9b9a082e3..67400dc41 100644 --- a/Indicator/tests/IndicatorTick.test.mq5 +++ b/Indicator/tests/IndicatorTick.test.mq5 @@ -26,50 +26,13 @@ // Includes. #include "../../Test.mqh" -#include "../IndicatorTick.h" - -// Structs. -struct IndicatorTickDummyParams : IndicatorParams { - IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} -}; - -/** - * Tick indicator is an indicator that provides per-tick information. - * When asked to return data via GetEntry() it could fetch data from pre-made - * tick history or generate tick on-the-fly from remote source and save it in - * the history. - * - * Note that indicators could provide data also for future shifts, so shift=-10 - * is perfectly valid for them when doing GetEntry()/GetValue(). - * - * Tick indicator may become a data source for Candle indicator. In this - * scenario, when trying to fetch candle for a given shift, tick indicator is - * asked for ticks in a given timespan. E.g., Candle indicator may work in a 5s - * timespans, so when fetching candle with shift now+1, Tick indicator will be - * asked for ticks between now+5s and now+10s. - *rmf - * In order to fetch consecutive candles, you have to call - * IndicatorCandle::NextMaybe() to check whether new candle is ready to be - * processed. If yes, then new candle will be at index 0. - * - * if (indi_candle.NextMaybe()) { - * double _open = indi_candle.Open(0); // Shift 0 = current candle. - * double _close = indi_candle.Close(0); // Shift 0 = current candle. - * } - */ -class IndicatorTickDummy : public IndicatorTick { - public: - IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { - SetSymbol(_symbol); - } -}; +#include "classes/IndicatorTickDummy.h" /** * Implements OnInit(). */ int OnInit() { - IndicatorTickDummy _indi_tick(_Symbol); + IndicatorTickDummy _indi_tick(PERIOD_CURRENT); long _time = 1; for (double _price = 0.1; _price <= 2.0; _price += 0.1) { MqlTick _tick; diff --git a/Indicator/tests/classes/IndicatorTickDummy.h b/Indicator/tests/classes/IndicatorTickDummy.h index 355659ff9..683025176 100644 --- a/Indicator/tests/classes/IndicatorTickDummy.h +++ b/Indicator/tests/classes/IndicatorTickDummy.h @@ -1,3 +1,38 @@ +//+------------------------------------------------------------------+ +//| 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 + * Dummy candle-based indicator. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../../../Tick.struct.h" +#include "../../IndicatorTick.h" + // Params for dummy tick-based indicator. struct IndicatorTickDummyParams : IndicatorParams { IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 2, TYPE_DOUBLE) {} @@ -6,10 +41,8 @@ struct IndicatorTickDummyParams : IndicatorParams { // Dummy tick-based indicator. class IndicatorTickDummy : public IndicatorTick { public: - IndicatorTickDummy(string _symbol, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _symbol, _shift, _name) { - SetSymbol(_symbol); - } + IndicatorTickDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} string GetName() override { return "IndicatorTickDummy"; } @@ -17,13 +50,22 @@ class IndicatorTickDummy : public IndicatorTick(1.0f, 1.01f))); - EmitEntry(TickToEntry(1500, TickAB(1.5f, 1.51f))); - EmitEntry(TickToEntry(2000, TickAB(2.0f, 2.01f))); - EmitEntry(TickToEntry(3000, TickAB(3.0f, 3.01f))); - EmitEntry(TickToEntry(4000, TickAB(4.0f, 4.01f))); - EmitEntry(TickToEntry(4100, TickAB(4.1f, 4.11f))); - EmitEntry(TickToEntry(4200, TickAB(4.2f, 4.21f))); - EmitEntry(TickToEntry(4800, TickAB(4.8f, 4.81f))); + TickAB _t1(1.0f, 1.01f); + TickAB _t2(1.5f, 1.51f); + TickAB _t3(2.0f, 2.01f); + TickAB _t4(3.0f, 3.01f); + TickAB _t5(4.0f, 4.01f); + TickAB _t6(4.1f, 4.11f); + TickAB _t7(4.2f, 4.21f); + TickAB _t8(4.8f, 4.81f); + + EmitEntry(TickToEntry(1000, _t1)); + EmitEntry(TickToEntry(1500, _t2)); + EmitEntry(TickToEntry(2000, _t3)); + EmitEntry(TickToEntry(3000, _t4)); + EmitEntry(TickToEntry(4000, _t5)); + EmitEntry(TickToEntry(4100, _t6)); + EmitEntry(TickToEntry(4200, _t7)); + EmitEntry(TickToEntry(4800, _t8)); }; }; diff --git a/IndicatorBase.h b/IndicatorBase.h index 71d0e5950..09fcdcd98 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -72,7 +72,7 @@ class IndicatorBase : public Chart { IndicatorCalculateCache cache; ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. long last_tick_time; // Time of the last Tick() call. - int flags; // Flags such as INDI_FLAG_INDEXABLE_BY_SHIFT. + int flags; // Flags such as INDI_FLAG_INDEXABLE_BY_SHIFT. public: /* Indicator enumerations */ @@ -140,7 +140,7 @@ class IndicatorBase : public Chart { } return GetEntry(_index); } - + /** * Access indicator entry data using [] operator via datetime. */ @@ -154,9 +154,7 @@ class IndicatorBase : public Chart { return GetEntry(_dt); } - IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { - return GetEntry((int)_index); - } + IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry((int)_index); } /* Buffer methods */ @@ -342,29 +340,18 @@ class IndicatorBase : public Chart { /** * Creates default, tick based indicator for given applied price. */ - IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) { - // Returning real candle indicator. Thus way we can use SetAppliedPrice() and select Ask or Bid price. - switch (_applied_price) { - case PRICE_ASK: - case PRICE_BID: - return new IndicatorTickReal(GetTf()); - case PRICE_OPEN: - case PRICE_HIGH: - case PRICE_LOW: - case PRICE_CLOSE: - case PRICE_MEDIAN: - case PRICE_TYPICAL: - case PRICE_WEIGHTED: - return new IndicatorTfDummy(GetTf()); - } - - Print("Passed wrong value for applied price for ", GetFullName(), " indicator!"); + virtual IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) { DebugBreak(); return NULL; } /* Getters */ + /** + * Returns indicator's flags. + */ + int GetFlags() { return flags; } + /** * Returns buffers' cache. */ @@ -662,7 +649,9 @@ class IndicatorBase : public Chart { * Returns the indicator's struct value. */ virtual IndicatorDataEntry GetEntry(datetime _dt) { - Print(GetFullName(), " must implement IndicatorDataEntry IndicatorBase::GetEntry(datetime _dt) in order to use GetEntry(datetime _dt) or _indi[datetime] subscript operator!"); + Print(GetFullName(), + " must implement IndicatorDataEntry IndicatorBase::GetEntry(datetime _dt) in order to use GetEntry(datetime " + "_dt) or _indi[datetime] subscript operator!"); DebugBreak(); IndicatorDataEntry _default; return _default; diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index cfb98b777..50d44420d 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -81,7 +81,7 @@ class Indi_BWMFI : public IndicatorTickOrCandleSource { static double iBWMFI(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, ENUM_BWMFI_BUFFER _mode = BWMFI_BUFFER, IndicatorBase *_obj = NULL) { #ifdef __MQL4__ - return ::iBWMFI(_symbol, _tf, _real_shift); + return ::iBWMFI(_symbol, _tf, _shift); #else // __MQL5__ int _handle = Object::IsValid(_obj) ? _obj.Get(IndicatorState::INDICATOR_STATE_PROP_HANDLE) : NULL; double _res[]; diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index c32f45482..9f03835b9 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -54,7 +54,8 @@ class Indi_TickMt : public IndicatorTick { */ Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTick(_p, _indi_src){}; - Indi_TickMt(string _symbol, int _shift = 0) : IndicatorTick(INDI_TICK, _symbol, _shift){}; + Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") + : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} /** * Returns the indicator's value. diff --git a/Indicators/Tick/tests/Indi_TickMt.test.mq5 b/Indicators/Tick/tests/Indi_TickMt.test.mq5 index 428552d78..e77d1ee23 100644 --- a/Indicators/Tick/tests/Indi_TickMt.test.mq5 +++ b/Indicators/Tick/tests/Indi_TickMt.test.mq5 @@ -28,7 +28,7 @@ * Test functionality of Indi_TickMt indicator class. */ -Indi_TickMt indi(_Symbol); +Indi_TickMt indi(PERIOD_CURRENT); /** * Implements Init event handler. diff --git a/Storage/ValueStorage.h b/Storage/ValueStorage.h index 36efe0049..3b019ba0e 100644 --- a/Storage/ValueStorage.h +++ b/Storage/ValueStorage.h @@ -91,16 +91,17 @@ enum ENUM_IPEAK { IPEAK_LOWEST, IPEAK_HIGHEST }; ValueStorage *_price = INDI.GetValueStorage(APPLIED_PRICE); \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) -#define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC(INDI, SYMBOL, TF, APPLIED_PRICE, KEY) \ - ValueStorage *_price; \ - if (_indi.HasSpecificAppliedPriceValueStorage(APPLIED_PRICE)) { \ - _price = INDI.GetSpecificAppliedPriceValueStorage(APPLIED_PRICE); \ - } else { \ - Print("Source indicator ", INDI.GetFullName(), \ - " cannot be used as it doesn't provide a single buffer to be used by target indicator!"); \ - DebugBreak(); \ - } \ - \ +#define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC(INDI, SYMBOL, TF, APPLIED_PRICE, KEY) \ + ValueStorage *_price; \ + if (_indi.HasSpecificAppliedPriceValueStorage(APPLIED_PRICE)) { \ + _price = INDI.GetSpecificAppliedPriceValueStorage(APPLIED_PRICE); \ + } else { \ + Print("Source indicator ", INDI.GetFullName(), \ + " cannot be used as it doesn't provide a single buffer to be used by target indicator! You may try to set " \ + "applied price/data source mode and try again."); \ + DebugBreak(); \ + } \ + \ INDICATOR_CALCULATE_POPULATE_CACHE(SYMBOL, TF, KEY) #define INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(INDI, SYMBOL, TF, KEY) \ diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 0120c35ea..e659d6c75 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -422,10 +422,11 @@ bool InitIndicators() { // AMA. IndiAMAParams ama_params(); + // Will use Candle indicator by default. However, in that case we need to specifiy applied price (excluding ASK and + // BID). ama_params.SetDataSourceType(IDATA_INDICATOR); Indi_AMA* _indi_ama = new Indi_AMA(ama_params); - // AMA will automatically sets its data source to Tick or Candle indicator by value of APPLIED_PRICE. - _indi_ama.SetAppliedPrice(PRICE_ASK); + _indi_ama.SetAppliedPrice(PRICE_OPEN); indis.Push(_indi_ama); // Original AMA. From 58f94f919b15c98af9995a8e82f098157bd9b84f Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 7 Jan 2022 18:49:46 +0100 Subject: [PATCH 49/81] Fixed bug with IndicatorBase::GetValue() which called GetEntryValue() with wrong order of mode and index parameters. --- Indicator.mqh | 2 +- IndicatorBase.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index 13dc6e974..66560fc15 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -1163,7 +1163,7 @@ class Indicator : public IndicatorBase { * @return * Returns DataParamEntry struct filled with a single value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { + IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) override { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); return GetEntry(_ishift)[_mode]; } diff --git a/IndicatorBase.h b/IndicatorBase.h index 09fcdcd98..6e5ec56b4 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -567,7 +567,7 @@ class IndicatorBase : public Chart { template T GetValue(int _index = 0, int _mode = 0) { T _out; - GetEntryValue(_index, _mode).Get(_out); + GetEntryValue(_mode, _index).Get(_out); return _out; } @@ -670,7 +670,7 @@ class IndicatorBase : public Chart { /** * Returns the indicator's entry value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _index = -1) = NULL; + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) = NULL; /** * Sends entry to listening indicators. From e9504938c5892ebf451f51364a41e3f9446989ca Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 12 Jan 2022 16:20:06 +0100 Subject: [PATCH 50/81] State of the art --- Indicator/IndicatorCandle.h | 37 +++++++++++++++++++++++++++---------- Indicators/Indi_AMA.mqh | 4 ++++ tests/IndicatorsTest.mq5 | 5 +++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 0fffc48ae..4293af43b 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -32,6 +32,7 @@ // Includes. #include "../Buffer/BufferCandle.h" #include "../Indicator.mqh" +#include "../Candle.struct.h" // Indicator modes. enum ENUM_INDI_CANDLE_MODE { @@ -95,20 +96,36 @@ class IndicatorCandle : public Indicator { * @return * Returns IndicatorDataEntry struct filled with indicator values. */ - IndicatorDataEntry GetEntry(int _index) override { + IndicatorDataEntry GetEntry(int _index = -1) override { ResetLastError(); unsigned int _ishift = _index >= 0 ? _index : iparams.GetShift(); long _candle_time = CalcCandleTimestamp(GetBarTime(_ishift)); - CandleOCTOHLC _candle = icdata.GetByKey(_candle_time); + long _curr_candle_time; + CandleOCTOHLC _candle; + // Trying current and older shifts. + if (icdata.Size() > 0) { + int i = 0; + while (true) { + _curr_candle_time = CalcCandleTimestamp(GetBarTime(i++)); + + if (_curr_candle_time < icdata.GetMin()) { + // There is no older entries. + break; + } + + _candle = icdata.GetByKey(_curr_candle_time); + + if (_candle.IsValid()) { + break; + } + } + } + if (!_candle.IsValid()) { -#ifdef __debug__ - Print(GetFullName(), ": Missing candle at shift ", _index, " (", TimeToString(_candle_time), ")"); -#endif - } else { -#ifdef __debug__verbose_ - Print(GetFullName(), ": Retrieving candle at shift ", _index, " (", TimeToString(_candle_time), ")"); -#endif + // Giving up. + DebugBreak(); + Print(GetFullName(), ": Missing candle after thorough search at shift ", _index, " (", TimeToString(_candle_time), "). Lowest timestamp in history is ", icdata.GetMin()); } return CandleToEntry(_candle_time, _candle); @@ -172,7 +189,7 @@ class IndicatorCandle : public Indicator { _candle.Update(_tick_timestamp, _price); } - icdata.Set(_candle_timestamp, _candle); + icdata.Add(_candle, _candle_timestamp); } /** diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 819ee824f..ee9e75af9 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -177,6 +177,10 @@ class Indi_AMA : public IndicatorTickOrCandleSource { CalculateInit(InpPeriodAMA, InpFastPeriodEMA, InpSlowPeriodEMA, InpShiftAMA, ExtFastSC, ExtSlowSC, ExtPeriodAMA, ExtSlowPeriodEMA, ExtFastPeriodEMA); + for (int x = prev_calculated; x < rates_total; ++x) { + Print("price[", x, "] = ", price[x].Get(), ", O = ", iOpen(Symbol(), PERIOD_CURRENT, Bars(Symbol(), PERIOD_CURRENT) - x - 1)); + } + int i; // Check for rates count. if (rates_total < ExtPeriodAMA + begin) return (0); diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index e659d6c75..357984ae5 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -112,9 +112,10 @@ void OnTick() { IndicatorDataEntry _entry(_indi.GetEntry()); if (_indi.GetType() == INDI_AMA) { - // PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); + PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); + continue; } else { - // continue; + continue; } if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { From 078af3aec1fbfc9911ee52aff17a07b134d20530 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 13 Jan 2022 16:10:38 +0100 Subject: [PATCH 51/81] Looks like there is nothing more to do with AMA. Differences are marginal. We need to test some other, more simple indicator like MA(on SMA) in order to be 100% sure there's no differences at all, as there shouldn't be. AMA may differ if it has too many historic entries at start. --- Indicator/tests/IndicatorTf.test.mq5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index 71385aecd..c9cb9d86f 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -107,6 +107,6 @@ void OnTick() { */ void OnDeinit(const int reason) { // Printing all grouped candles. - // Print(indi_tf.Ptr().GetName(), "'s all candles:"); - // Print(indi_tf.Ptr().CandlesToString()); + Print(indi_tf_orig_sim.Ptr().GetName(), "'s all candles:"); + Print(indi_tf_orig_sim.Ptr().CandlesToString()); } From af586ee03eb455574ad289382f37099520328103 Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 17 Jan 2022 14:03:48 +0000 Subject: [PATCH 52/81] Moves Deal enums to Deal.enum.h --- Deal.enum.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Order.mqh | 1 + Std.h | 55 ++---------------------------------- 3 files changed, 84 insertions(+), 52 deletions(-) create mode 100644 Deal.enum.h diff --git a/Deal.enum.h b/Deal.enum.h new file mode 100644 index 000000000..ceef21a7f --- /dev/null +++ b/Deal.enum.h @@ -0,0 +1,80 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Includes Deal's enums. + */ + +#ifndef __MQL__ +enum ENUM_DEAL_TYPE { + DEAL_TYPE_BUY, + DEAL_TYPE_SELL, + DEAL_TYPE_BALANCE, + DEAL_TYPE_CREDIT, + DEAL_TYPE_CHARGE, + DEAL_TYPE_CORRECTION, + DEAL_TYPE_BONUS, + DEAL_TYPE_COMMISSION, + DEAL_TYPE_COMMISSION_DAILY, + DEAL_TYPE_COMMISSION_MONTHLY, + DEAL_TYPE_COMMISSION_AGENT_DAILY, + DEAL_TYPE_COMMISSION_AGENT_MONTHLY, + DEAL_TYPE_INTEREST, + DEAL_TYPE_BUY_CANCELED, + DEAL_TYPE_SELL_CANCELED, + DEAL_DIVIDEND, + DEAL_DIVIDEND_FRANKED, + DEAL_TAX +}; + +enum ENUM_DEAL_ENTRY { DEAL_ENTRY_IN, DEAL_ENTRY_OUT, DEAL_ENTRY_INOUT, DEAL_ENTRY_OUT_BY }; + +enum ENUM_DEAL_REASON { + DEAL_REASON_CLIENT, + DEAL_REASON_MOBILE, + DEAL_REASON_WEB, + DEAL_REASON_EXPERT, + DEAL_REASON_SL, + DEAL_REASON_TP, + DEAL_REASON_SO, + DEAL_REASON_ROLLOVER, + DEAL_REASON_VMARGIN, + DEAL_REASON_SPLIT +}; + +enum ENUM_DEAL_PROPERTY_DOUBLE { DEAL_VOLUME, DEAL_PRICE, DEAL_COMMISSION, DEAL_SWAP, DEAL_PROFIT, DEAL_FEE }; + +enum ENUM_DEAL_PROPERTY_INTEGER { + DEAL_TICKET, + DEAL_ORDER, + DEAL_TIME, + DEAL_TIME_MSC, + DEAL_TYPE, + DEAL_ENTRY, + DEAL_MAGIC, + DEAL_REASON, + DEAL_POSITION_ID +}; + +enum ENUM_DEAL_PROPERTY_STRING { DEAL_SYMBOL, DEAL_COMMENT, DEAL_EXTERNAL_ID }; +#endif diff --git a/Order.mqh b/Order.mqh index 7cbba164b..10f8b57a8 100644 --- a/Order.mqh +++ b/Order.mqh @@ -34,6 +34,7 @@ #include "Convert.mqh" #include "Data.define.h" #include "Data.struct.h" +#include "Deal.enum.h" #include "Log.mqh" #include "Order.define.h" #include "Order.enum.h" diff --git a/Std.h b/Std.h index 50cfd5cc1..1b7d70ab2 100644 --- a/Std.h +++ b/Std.h @@ -32,7 +32,10 @@ #include #include +// Data types. +typedef std::string string; typedef unsigned int uint; +typedef unsigned long datetime; typedef unsigned long ulong; typedef unsigned short ushort; #endif @@ -267,58 +270,6 @@ enum ENUM_ORDER_STATE { ORDER_STATE_REQUEST_CANCEL // Order is being deleted (deleting from the trading system) }; -enum ENUM_DEAL_TYPE { - DEAL_TYPE_BUY, - DEAL_TYPE_SELL, - DEAL_TYPE_BALANCE, - DEAL_TYPE_CREDIT, - DEAL_TYPE_CHARGE, - DEAL_TYPE_CORRECTION, - DEAL_TYPE_BONUS, - DEAL_TYPE_COMMISSION, - DEAL_TYPE_COMMISSION_DAILY, - DEAL_TYPE_COMMISSION_MONTHLY, - DEAL_TYPE_COMMISSION_AGENT_DAILY, - DEAL_TYPE_COMMISSION_AGENT_MONTHLY, - DEAL_TYPE_INTEREST, - DEAL_TYPE_BUY_CANCELED, - DEAL_TYPE_SELL_CANCELED, - DEAL_DIVIDEND, - DEAL_DIVIDEND_FRANKED, - DEAL_TAX -}; - -enum ENUM_DEAL_ENTRY { DEAL_ENTRY_IN, DEAL_ENTRY_OUT, DEAL_ENTRY_INOUT, DEAL_ENTRY_OUT_BY }; - -enum ENUM_DEAL_REASON { - DEAL_REASON_CLIENT, - DEAL_REASON_MOBILE, - DEAL_REASON_WEB, - DEAL_REASON_EXPERT, - DEAL_REASON_SL, - DEAL_REASON_TP, - DEAL_REASON_SO, - DEAL_REASON_ROLLOVER, - DEAL_REASON_VMARGIN, - DEAL_REASON_SPLIT -}; - -enum ENUM_DEAL_PROPERTY_DOUBLE { DEAL_VOLUME, DEAL_PRICE, DEAL_COMMISSION, DEAL_SWAP, DEAL_PROFIT, DEAL_FEE }; - -enum ENUM_DEAL_PROPERTY_INTEGER { - DEAL_TICKET, - DEAL_ORDER, - DEAL_TIME, - DEAL_TIME_MSC, - DEAL_TYPE, - DEAL_ENTRY, - DEAL_MAGIC, - DEAL_REASON, - DEAL_POSITION_ID -}; - -enum ENUM_DEAL_PROPERTY_STRING { DEAL_SYMBOL, DEAL_COMMENT, DEAL_EXTERNAL_ID }; - // @see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest struct MqlTradeRequest { ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type. From f6fb49646ef875fd89c552ecf32ed945ffa3b3fe Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 17 Jan 2022 14:14:34 +0000 Subject: [PATCH 53/81] Moves enums and structs from Std and MQL5 to appropriate files --- MQL5.mqh | 88 --------------- Order.enum.h | 38 +++++++ Order.struct.h | 35 ++++++ Pattern.struct.h | 2 +- Std.h | 254 -------------------------------------------- SymbolInfo.define.h | 10 ++ SymbolInfo.enum.h | 7 ++ SymbolInfo.static.h | 1 + SymbolInfo.struct.h | 1 + Terminal.define.h | 179 +++++++++++++++++++++++++++++++ 10 files changed, 272 insertions(+), 343 deletions(-) diff --git a/MQL5.mqh b/MQL5.mqh index e230f6f61..584a74fd2 100644 --- a/MQL5.mqh +++ b/MQL5.mqh @@ -307,92 +307,4 @@ #define ERR_USER_ERROR_FIRST 65536 // User defined errors start with this code. #endif -/** - * MQL5 wrapper to work in MQL4. - */ -class MQL5 { - - public: - // Enums. - #ifdef __MQL4__ - // Trading operations. - enum ENUM_TRADE_REQUEST_ACTIONS { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/enum_trade_request_actions - TRADE_ACTION_DEAL, // Place a trade order for an immediate execution with the specified parameters (market order). - TRADE_ACTION_PENDING, // Place a trade order for the execution under specified conditions (pending order). - TRADE_ACTION_SLTP, // Modify Stop Loss and Take Profit values of an opened position. - TRADE_ACTION_MODIFY, // Modify the parameters of the order placed previously. - TRADE_ACTION_REMOVE, // Delete the pending order placed previously. - TRADE_ACTION_CLOSE_BY // Close a position by an opposite one. - }; - // Fill Policy. - enum ENUM_SYMBOL_FILLING { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - SYMBOL_FILLING_FOK = 1, // A deal can be executed only with the specified volume. - SYMBOL_FILLING_IOC = 2 // Trader agrees to execute a deal with the volume maximally available in the market. - }; - enum ENUM_ORDER_TYPE_FILLING { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - ORDER_FILLING_FOK, // An order can be filled only in the specified amount. - ORDER_FILLING_IOC, // A trader agrees to execute a deal with the volume maximally available in the market. - ORDER_FILLING_RETURN // In case of partial filling a market or limit order with remaining volume is not canceled but processed further. - }; - enum ENUM_ORDER_TYPE_TIME { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - ORDER_TIME_GTC, // Good till cancel order. - ORDER_TIME_DAY, // Good till current trade day order. - ORDER_TIME_SPECIFIED, // Good till expired order. - ORDER_TIME_SPECIFIED_DAY // The order will be effective till 23:59:59 of the specified day. - }; - // An order status that describes its state. - enum ENUM_ORDER_STATE { - ORDER_STATE_STARTED, // Order checked, but not yet accepted by broker - ORDER_STATE_PLACED, // Order accepted - ORDER_STATE_CANCELED, // Order canceled by client - ORDER_STATE_PARTIAL, // Order partially executed - ORDER_STATE_FILLED, // Order fully executed - ORDER_STATE_REJECTED, // Order rejected - ORDER_STATE_EXPIRED, // Order expired - ORDER_STATE_REQUEST_ADD, // Order is being registered (placing to the trading system) - ORDER_STATE_REQUEST_MODIFY, // Order is being modified (changing its parameters) - ORDER_STATE_REQUEST_CANCEL // Order is being deleted (deleting from the trading system) - }; - #endif - - #ifdef __MQL4__ - // @see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest - struct MqlTradeRequest { - ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type. - ulong magic; // Expert Advisor ID (magic number). - ulong order; // Order ticket. - string symbol; // Trade symbol. - double volume; // Requested volume for a deal in lots. - double price; // Price. - double stoplimit; // StopLimit level of the order. - double sl; // Stop Loss level of the order. - double tp; // Take Profit level of the order. - ulong deviation; // Maximal possible deviation from the requested price. - ENUM_ORDER_TYPE type; // Order type. - ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type. - ENUM_ORDER_TYPE_TIME type_time; // Order expiration type. - datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type. - string comment; // Order comment. - ulong position; // Position ticket. - ulong position_by; // The ticket of an opposite position. - }; - // @see: https://www.mql5.com/en/docs/constants/structures/mqltraderesult - struct MqlTradeResult { - uint retcode; // Operation return code. - ulong deal; // Deal ticket, if it is performed. - ulong order; // Order ticket, if it is placed. - double volume; // Deal volume, confirmed by broker. - double price; // Deal price, confirmed by broker. - double bid; // Current Bid price. - double ask; // Current Ask price. - string comment; // Broker comment to operation (by default it is filled by description of trade server return code). - uint request_id; // Request ID set by the terminal during the dispatch. - uint retcode_external; // Return code of an external trading system. - }; - #endif -}; #endif // MQL5_MQH diff --git a/Order.enum.h b/Order.enum.h index 385aebb30..c6489a73d 100644 --- a/Order.enum.h +++ b/Order.enum.h @@ -114,6 +114,33 @@ enum ENUM_ORDER_REASON { ORDER_REASON_TP, // The order was placed as a result of Take Profit activation. ORDER_REASON_WEB, // The order was placed from a web platform. }; +// An order status that describes its state. +enum ENUM_ORDER_STATE { + ORDER_STATE_STARTED, // Order checked, but not yet accepted by broker + ORDER_STATE_PLACED, // Order accepted + ORDER_STATE_CANCELED, // Order canceled by client + ORDER_STATE_PARTIAL, // Order partially executed + ORDER_STATE_FILLED, // Order fully executed + ORDER_STATE_REJECTED, // Order rejected + ORDER_STATE_EXPIRED, // Order expired + ORDER_STATE_REQUEST_ADD, // Order is being registered (placing to the trading system) + ORDER_STATE_REQUEST_MODIFY, // Order is being modified (changing its parameters) + ORDER_STATE_REQUEST_CANCEL // Order is being deleted (deleting from the trading system) +}; +enum ENUM_ORDER_TYPE_FILLING { + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties + ORDER_FILLING_FOK, // An order can be filled only in the specified amount. + ORDER_FILLING_IOC, // A trader agrees to execute a deal with the volume maximally available in the market. + ORDER_FILLING_RETURN // In case of partial filling a market or limit order with remaining volume is not canceled but + // processed further. +}; +enum ENUM_ORDER_TYPE_TIME { + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties + ORDER_TIME_GTC, // Good till cancel order. + ORDER_TIME_DAY, // Good till current trade day order. + ORDER_TIME_SPECIFIED, // Good till expired order. + ORDER_TIME_SPECIFIED_DAY // The order will be effective till 23:59:59 of the specified day. +}; #endif #ifndef __MQ4__ @@ -294,4 +321,15 @@ enum ENUM_POSITION_TYPE { POSITION_TYPE_BUY, // Buy position. POSITION_TYPE_SELL // Sell position. }; + +// Trading operations. +enum ENUM_TRADE_REQUEST_ACTIONS { + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/enum_trade_request_actions + TRADE_ACTION_DEAL, // Place a trade order for an immediate execution with the specified parameters (market order). + TRADE_ACTION_PENDING, // Place a trade order for the execution under specified conditions (pending order). + TRADE_ACTION_SLTP, // Modify Stop Loss and Take Profit values of an opened position. + TRADE_ACTION_MODIFY, // Modify the parameters of the order placed previously. + TRADE_ACTION_REMOVE, // Delete the pending order placed previously. + TRADE_ACTION_CLOSE_BY // Close a position by an opposite one. +}; #endif diff --git a/Order.struct.h b/Order.struct.h index 0fbda897c..6c77c0aa5 100644 --- a/Order.struct.h +++ b/Order.struct.h @@ -54,6 +54,41 @@ struct MqlTradeCheckResult { double margin_level; // Margin level. string comment; // Comment to the reply code (description of the error). }; + +// @see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest +struct MqlTradeRequest { + ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type. + ulong magic; // Expert Advisor ID (magic number). + ulong order; // Order ticket. + string symbol; // Trade symbol. + double volume; // Requested volume for a deal in lots. + double price; // Price. + double stoplimit; // StopLimit level of the order. + double sl; // Stop Loss level of the order. + double tp; // Take Profit level of the order. + ulong deviation; // Maximal possible deviation from the requested price. + ENUM_ORDER_TYPE type; // Order type. + ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type. + ENUM_ORDER_TYPE_TIME type_time; // Order expiration type. + datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type. + string comment; // Order comment. + ulong position; // Position ticket. + ulong position_by; // The ticket of an opposite position. +}; + +// @see: https://www.mql5.com/en/docs/constants/structures/mqltraderesult +struct MqlTradeResult { + uint retcode; // Operation return code. + ulong deal; // Deal ticket, if it is performed. + ulong order; // Order ticket, if it is placed. + double volume; // Deal volume, confirmed by broker. + double price; // Deal price, confirmed by broker. + double bid; // Current Bid price. + double ask; // Current Ask price. + string comment; // Broker comment to operation (by default it is filled by description of trade server return code). + uint request_id; // Request ID set by the terminal during the dispatch. + uint retcode_external; // Return code of an external trading system. +}; #endif /** diff --git a/Pattern.struct.h b/Pattern.struct.h index 2297c7c51..83422f4a6 100644 --- a/Pattern.struct.h +++ b/Pattern.struct.h @@ -32,8 +32,8 @@ // Includes. #include "Bar.struct.h" -#include "Pattern.enum.h" #include "Math.define.h" +#include "Pattern.enum.h" // Defines structure for bitwise pattern values. struct PatternBitwise { diff --git a/Std.h b/Std.h index 1b7d70ab2..22a6318e3 100644 --- a/Std.h +++ b/Std.h @@ -223,224 +223,6 @@ const char* cstring_from(const std::string& _value) { return _value.c_str(); } #endif #ifndef __MQL__ -/** - * @file - * Includes MQL-compatible enumerations. - */ -enum ENUM_TRADE_REQUEST_ACTIONS { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/enum_trade_request_actions - TRADE_ACTION_DEAL, // Place a trade order for an immediate execution with the specified parameters (market order). - TRADE_ACTION_PENDING, // Place a trade order for the execution under specified conditions (pending order). - TRADE_ACTION_SLTP, // Modify Stop Loss and Take Profit values of an opened position. - TRADE_ACTION_MODIFY, // Modify the parameters of the order placed previously. - TRADE_ACTION_REMOVE, // Delete the pending order placed previously. - TRADE_ACTION_CLOSE_BY // Close a position by an opposite one. -}; -// Fill Policy. -enum ENUM_SYMBOL_FILLING { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - SYMBOL_FILLING_FOK = 1, // A deal can be executed only with the specified volume. - SYMBOL_FILLING_IOC = 2 // Trader agrees to execute a deal with the volume maximally available in the market. -}; -enum ENUM_ORDER_TYPE_FILLING { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - ORDER_FILLING_FOK, // An order can be filled only in the specified amount. - ORDER_FILLING_IOC, // A trader agrees to execute a deal with the volume maximally available in the market. - ORDER_FILLING_RETURN // In case of partial filling a market or limit order with remaining volume is not canceled but - // processed further. -}; -enum ENUM_ORDER_TYPE_TIME { - // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties - ORDER_TIME_GTC, // Good till cancel order. - ORDER_TIME_DAY, // Good till current trade day order. - ORDER_TIME_SPECIFIED, // Good till expired order. - ORDER_TIME_SPECIFIED_DAY // The order will be effective till 23:59:59 of the specified day. -}; -// An order status that describes its state. -enum ENUM_ORDER_STATE { - ORDER_STATE_STARTED, // Order checked, but not yet accepted by broker - ORDER_STATE_PLACED, // Order accepted - ORDER_STATE_CANCELED, // Order canceled by client - ORDER_STATE_PARTIAL, // Order partially executed - ORDER_STATE_FILLED, // Order fully executed - ORDER_STATE_REJECTED, // Order rejected - ORDER_STATE_EXPIRED, // Order expired - ORDER_STATE_REQUEST_ADD, // Order is being registered (placing to the trading system) - ORDER_STATE_REQUEST_MODIFY, // Order is being modified (changing its parameters) - ORDER_STATE_REQUEST_CANCEL // Order is being deleted (deleting from the trading system) -}; - -// @see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest -struct MqlTradeRequest { - ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type. - ulong magic; // Expert Advisor ID (magic number). - ulong order; // Order ticket. - string symbol; // Trade symbol. - double volume; // Requested volume for a deal in lots. - double price; // Price. - double stoplimit; // StopLimit level of the order. - double sl; // Stop Loss level of the order. - double tp; // Take Profit level of the order. - ulong deviation; // Maximal possible deviation from the requested price. - ENUM_ORDER_TYPE type; // Order type. - ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type. - ENUM_ORDER_TYPE_TIME type_time; // Order expiration type. - datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type. - string comment; // Order comment. - ulong position; // Position ticket. - ulong position_by; // The ticket of an opposite position. -}; -// @see: https://www.mql5.com/en/docs/constants/structures/mqltraderesult -struct MqlTradeResult { - uint retcode; // Operation return code. - ulong deal; // Deal ticket, if it is performed. - ulong order; // Order ticket, if it is placed. - double volume; // Deal volume, confirmed by broker. - double price; // Deal price, confirmed by broker. - double bid; // Current Bid price. - double ask; // Current Ask price. - string comment; // Broker comment to operation (by default it is filled by description of trade server return code). - uint request_id; // Request ID set by the terminal during the dispatch. - uint retcode_external; // Return code of an external trading system. -}; - -#define ERR_USER_ERROR_FIRST 65536 // User defined errors start with this code. - -#define AliceBlue 0xFFF8F0 -#define AntiqueWhite 0xD7EBFA -#define Aqua 0xFFFF00 -#define Aquamarine 0xD4FF7F -#define Beige 0xDCF5F5 -#define Bisque 0xC4E4FF -#define Black 0x000000 -#define BlanchedAlmond 0xCDEBFF -#define Blue 0xFF0000 -#define BlueViolet 0xE22B8A -#define Brown 0x2A2AA5 -#define BurlyWood 0x87B8DE -#define CadetBlue 0xA09E5F -#define Chartreuse 0x00FF7F -#define Chocolate 0x1E69D2 -#define Coral 0x507FFF -#define CornflowerBlue 0xED9564 -#define Cornsilk 0xDCF8FF -#define Crimson 0x3C14DC -#define DarkBlue 0x8B0000 -#define DarkGoldenrod 0x0B86B8 -#define DarkGray 0xA9A9A9 -#define DarkGreen 0x006400 -#define DarkKhaki 0x6BB7BD -#define DarkOliveGreen 0x2F6B55 -#define DarkOrange 0x008CFF -#define DarkOrchid 0xCC3299 -#define DarkSalmon 0x7A96E9 -#define DarkSeaGreen 0x8BBC8F -#define DarkSlateBlue 0x8B3D48 -#define DarkSlateGray 0x4F4F2F -#define DarkTurquoise 0xD1CE00 -#define DarkViolet 0xD30094 -#define DeepPink 0x9314FF -#define DeepSkyBlue 0xFFBF00 -#define DimGray 0x696969 -#define DodgerBlue 0xFF901E -#define FireBrick 0x2222B2 -#define ForestGreen 0x228B22 -#define Gainsboro 0xDCDCDC -#define Gold 0x00D7FF -#define Goldenrod 0x20A5DA -#define Gray 0x808080 -#define Green 0x008000 -#define GreenYellow 0x2FFFAD -#define Honeydew 0xF0FFF0 -#define HotPink 0xB469FF -#define IndianRed 0x5C5CCD -#define Indigo 0x82004B -#define Ivory 0xF0FFFF -#define Khaki 0x8CE6F0 -#define Lavender 0xFAE6E6 -#define LavenderBlush 0xF5F0FF -#define LawnGreen 0x00FC7C -#define LemonChiffon 0xCDFAFF -#define LightBlue 0xE6D8AD -#define LightCoral 0x8080F0 -#define LightCyan 0xFFFFE0 -#define LightGoldenrod 0xD2FAFA -#define LightGray 0xD3D3D3 -#define LightGreen 0x90EE90 -#define LightPink 0xC1B6FF -#define LightSalmon 0x7AA0FF -#define LightSeaGreen 0xAAB220 -#define LightSkyBlue 0xFACE87 -#define LightSlateGray 0x998877 -#define LightSteelBlue 0xDEC4B0 -#define LightYellow 0xE0FFFF -#define Lime 0x00FF00 -#define LimeGreen 0x32CD32 -#define Linen 0xE6F0FA -#define Magenta 0xFF00FF -#define Maroon 0x000080 -#define MediumAquamarine 0xAACD66 -#define MediumBlue 0xCD0000 -#define MediumOrchid 0xD355BA -#define MediumPurple 0xDB7093 -#define MediumSeaGreen 0x71B33C -#define MediumSlateBlue 0xEE687B -#define MediumSpringGreen 0x9AFA00 -#define MediumTurquoise 0xCCD148 -#define MediumVioletRed 0x8515C7 -#define MidnightBlue 0x701919 -#define MintCream 0xFAFFF5 -#define MistyRose 0xE1E4FF -#define Moccasin 0xB5E4FF -#define NavajoWhite 0xADDEFF -#define Navy 0x800000 -#define OldLace 0xE6F5FD -#define Olive 0x008080 -#define OliveDrab 0x238E6B -#define Orange 0x00A5FF -#define OrangeRed 0x0045FF -#define Orchid 0xD670DA -#define PaleGoldenrod 0xAAE8EE -#define PaleGreen 0x98FB98 -#define PaleTurquoise 0xEEEEAF -#define PaleVioletRed 0x9370DB -#define PapayaWhip 0xD5EFFF -#define PeachPuff 0xB9DAFF -#define Peru 0x3F85CD -#define Pink 0xCBC0FF -#define Plum 0xDDA0DD -#define PowderBlue 0xE6E0B0 -#define Purple 0x800080 -#define Red 0x0000FF -#define RosyBrown 0x8F8FBC -#define RoyalBlue 0xE16941 -#define SaddleBrown 0x13458B -#define Salmon 0x7280FA -#define SandyBrown 0x60A4F4 -#define SeaGreen 0x578B2E -#define Seashell 0xEEF5FF -#define Sienna 0x2D52A0 -#define Silver 0xC0C0C0 -#define SkyBlue 0xEBCE87 -#define SlateBlue 0xCD5A6A -#define SlateGray 0x908070 -#define Snow 0xFAFAFF -#define SpringGreen 0x7FFF00 -#define SteelBlue 0xB48246 -#define Tan 0x8CB4D2 -#define Teal 0x808000 -#define Thistle 0xD8BFD8 -#define Tomato 0x4763FF -#define Turquoise 0xD0E040 -#define Violet 0xEE82EE -#define Wheat 0xB3DEF5 -#define White 0xFFFFFF -#define WhiteSmoke 0xF5F5F5 -#define Yellow 0x00FFFF -#define YellowGreen 0x32CD9A -#define clrNONE -1 -#define CLR_NONE -1 - // Additional enum values for ENUM_SYMBOL_INFO_DOUBLE #define SYMBOL_MARGIN_LIMIT ((ENUM_SYMBOL_INFO_DOUBLE)46) #define SYMBOL_MARGIN_MAINTENANCE ((ENUM_SYMBOL_INFO_DOUBLE)43) @@ -448,42 +230,6 @@ struct MqlTradeResult { #define SYMBOL_MARGIN_SHORT ((ENUM_SYMBOL_INFO_DOUBLE)45) #define SYMBOL_MARGIN_STOP ((ENUM_SYMBOL_INFO_DOUBLE)47) #define SYMBOL_MARGIN_STOPLIMIT ((ENUM_SYMBOL_INFO_DOUBLE)48) - -#define TRADE_RETCODE_REQUOTE 10004 // Requote -#define TRADE_RETCODE_REJECT 10006 // Request rejected -#define TRADE_RETCODE_CANCEL 10007 // Request canceled by trader -#define TRADE_RETCODE_PLACED 10008 // Order placed -#define TRADE_RETCODE_DONE 10009 // Request completed -#define TRADE_RETCODE_DONE_PARTIAL 10010 // Only part of the request was completed -#define TRADE_RETCODE_ERROR 10011 // Request processing error -#define TRADE_RETCODE_TIMEOUT 10012 // Request canceled by timeout -#define TRADE_RETCODE_INVALID 10013 // Invalid request -#define TRADE_RETCODE_INVALID_VOLUME 10014 // Invalid volume in the request -#define TRADE_RETCODE_INVALID_PRICE 10015 // Invalid price in the request -#define TRADE_RETCODE_INVALID_STOPS 10016 // Invalid stops in the request -#define TRADE_RETCODE_TRADE_DISABLED 10017 // Trade is disabled -#define TRADE_RETCODE_MARKET_CLOSED 10018 // Market is closed -#define TRADE_RETCODE_NO_MONEY 10019 // There is not enough money to complete the request -#define TRADE_RETCODE_PRICE_CHANGED 10020 // Prices changed -#define TRADE_RETCODE_PRICE_OFF 10021 // There are no quotes to process the request -#define TRADE_RETCODE_INVALID_EXPIRATION 10022 // Invalid order expiration date in the request -#define TRADE_RETCODE_ORDER_CHANGED 10023 // Order state changed -#define TRADE_RETCODE_TOO_MANY_REQUESTS 10024 // Too frequent requests -#define TRADE_RETCODE_NO_CHANGES 10025 // No changes in request -#define TRADE_RETCODE_SERVER_DISABLES_AT 10026 // Autotrading disabled by server -#define TRADE_RETCODE_CLIENT_DISABLES_AT 10027 // Autotrading disabled by client terminal -#define TRADE_RETCODE_LOCKED 10028 // Request locked for processing -#define TRADE_RETCODE_FROZEN 10029 // Order or position frozen -#define TRADE_RETCODE_INVALID_FILL 10030 // Invalid order filling type -#define TRADE_RETCODE_CONNECTION 10031 // No connection with the trade server -#define TRADE_RETCODE_ONLY_REAL 10032 // Operation is allowed only for live accounts -#define TRADE_RETCODE_LIMIT_ORDERS 10033 // The number of pending orders has reached the limit -#define TRADE_RETCODE_LIMIT_VOLUME 10034 // The volume of orders and positions for the symbol has reached the limit -#define TRADE_RETCODE_INVALID_ORDER 10035 // Incorrect or prohibited order type -#define TRADE_RETCODE_POSITION_CLOSED 10036 // Position with the specified POSITION_IDENTIFIER has already been closed -#define TRADE_RETCODE_INVALID_CLOSE_VOLUME 10038 // A close volume exceeds the current position volume -#define TRADE_RETCODE_CLOSE_ORDER_EXIST 10039 // A close order already exists. -#define TRADE_RETCODE_LIMIT_POSITIONS 10040 // The number of open positions can be limited (e.g. Netting, Hedging). #endif #ifndef __MQL__ diff --git a/SymbolInfo.define.h b/SymbolInfo.define.h index 68ef4c107..960369f2d 100644 --- a/SymbolInfo.define.h +++ b/SymbolInfo.define.h @@ -32,3 +32,13 @@ #define Point _Point #define Digits _Digits #endif + +#ifndef __MQL__ +// Additional enum values for ENUM_SYMBOL_INFO_DOUBLE +#define SYMBOL_MARGIN_LIMIT ((ENUM_SYMBOL_INFO_DOUBLE)46) +#define SYMBOL_MARGIN_MAINTENANCE ((ENUM_SYMBOL_INFO_DOUBLE)43) +#define SYMBOL_MARGIN_LONG ((ENUM_SYMBOL_INFO_DOUBLE)44) +#define SYMBOL_MARGIN_SHORT ((ENUM_SYMBOL_INFO_DOUBLE)45) +#define SYMBOL_MARGIN_STOP ((ENUM_SYMBOL_INFO_DOUBLE)47) +#define SYMBOL_MARGIN_STOPLIMIT ((ENUM_SYMBOL_INFO_DOUBLE)48) +#endif diff --git a/SymbolInfo.enum.h b/SymbolInfo.enum.h index 59a3ffdfc..43b625853 100644 --- a/SymbolInfo.enum.h +++ b/SymbolInfo.enum.h @@ -31,6 +31,13 @@ #endif #ifndef __MQL5__ +// Fill Policy. +enum ENUM_SYMBOL_FILLING { + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties + SYMBOL_FILLING_FOK = 1, // A deal can be executed only with the specified volume. + SYMBOL_FILLING_IOC = 2 // Trader agrees to execute a deal with the volume maximally available in the market. +}; + // Methods of swap calculation at position transfer. // @see: https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants#enum_symbol_swap_mode enum ENUM_SYMBOL_SWAP_MODE { diff --git a/SymbolInfo.static.h b/SymbolInfo.static.h index 3ce588682..cf5d7f2bf 100644 --- a/SymbolInfo.static.h +++ b/SymbolInfo.static.h @@ -27,6 +27,7 @@ #include "MQL5.mqh" #include "MqlTick.h" +#include "Order.enum.h" #include "Std.h" /** diff --git a/SymbolInfo.struct.h b/SymbolInfo.struct.h index 04ea0e0b5..91b95c1cf 100644 --- a/SymbolInfo.struct.h +++ b/SymbolInfo.struct.h @@ -33,6 +33,7 @@ // Includes. #include "ISerializable.h" #include "MqlTick.h" +#include "Std.h" #include "SymbolInfo.static.h" // Defines struct to store symbol data. diff --git a/Terminal.define.h b/Terminal.define.h index 7484aafb7..ef833c2da 100644 --- a/Terminal.define.h +++ b/Terminal.define.h @@ -27,6 +27,144 @@ /* Defines */ +// Colors. +#define AliceBlue 0xFFF8F0 +#define AntiqueWhite 0xD7EBFA +#define Aqua 0xFFFF00 +#define Aquamarine 0xD4FF7F +#define Beige 0xDCF5F5 +#define Bisque 0xC4E4FF +#define Black 0x000000 +#define BlanchedAlmond 0xCDEBFF +#define Blue 0xFF0000 +#define BlueViolet 0xE22B8A +#define Brown 0x2A2AA5 +#define BurlyWood 0x87B8DE +#define CadetBlue 0xA09E5F +#define Chartreuse 0x00FF7F +#define Chocolate 0x1E69D2 +#define Coral 0x507FFF +#define CornflowerBlue 0xED9564 +#define Cornsilk 0xDCF8FF +#define Crimson 0x3C14DC +#define DarkBlue 0x8B0000 +#define DarkGoldenrod 0x0B86B8 +#define DarkGray 0xA9A9A9 +#define DarkGreen 0x006400 +#define DarkKhaki 0x6BB7BD +#define DarkOliveGreen 0x2F6B55 +#define DarkOrange 0x008CFF +#define DarkOrchid 0xCC3299 +#define DarkSalmon 0x7A96E9 +#define DarkSlateBlue 0x8B3D48 +#define DarkSlateGray 0x4F4F2F +#define DarkTurquoise 0xD1CE00 +#define DarkViolet 0xD30094 +#define DeepPink 0x9314FF +#define DeepSkyBlue 0xFFBF00 +#define DimGray 0x696969 +#define DodgerBlue 0xFF901E +#define FireBrick 0x2222B2 +#define ForestGreen 0x228B22 +#define Gainsboro 0xDCDCDC +#define Gold 0x00D7FF +#define Goldenrod 0x20A5DA +#define Gray 0x808080 +#define Green 0x008000 +#define GreenYellow 0x2FFFAD +#define Honeydew 0xF0FFF0 +#define HotPink 0xB469FF +#define IndianRed 0x5C5CCD +#define Indigo 0x82004B +#define Ivory 0xF0FFFF +#define Khaki 0x8CE6F0 +#define Lavender 0xFAE6E6 +#define LavenderBlush 0xF5F0FF +#define LawnGreen 0x00FC7C +#define LemonChiffon 0xCDFAFF +#define LightBlue 0xE6D8AD +#define LightCoral 0x8080F0 +#define LightCyan 0xFFFFE0 +#define LightGoldenrod 0xD2FAFA +#define LightGray 0xD3D3D3 +#define LightGreen 0x90EE90 +#define LightPink 0xC1B6FF +#define LightSalmon 0x7AA0FF +#define LightSeaGreen 0xAAB220 +#define LightSkyBlue 0xFACE87 +#define LightSlateGray 0x998877 +#define LightSteelBlue 0xDEC4B0 +#define LightYellow 0xE0FFFF +#define Lime 0x00FF00 +#define LimeGreen 0x32CD32 +#define Linen 0xE6F0FA +#define Magenta 0xFF00FF +#define Maroon 0x000080 +#define MediumAquamarine 0xAACD66 +#define MediumBlue 0xCD0000 +#define MediumOrchid 0xD355BA +#define MediumPurple 0xDB7093 +#define MediumSeaGreen 0x71B33C +#define MediumSlateBlue 0xEE687B +#define MediumSpringGreen 0x9AFA00 +#define MediumTurquoise 0xCCD148 +#define MediumVioletRed 0x8515C7 +#define MidnightBlue 0x701919 +#define MintCream 0xFAFFF5 +#define MistyRose 0xE1E4FF +#define Moccasin 0xB5E4FF +#define NavajoWhite 0xADDEFF +#define Navy 0x800000 +#define OldLace 0xE6F5FD +#define Olive 0x008080 +#define OliveDrab 0x238E6B +#define Orange 0x00A5FF +#define OrangeRed 0x0045FF +#define Orchid 0xD670DA +#define PaleGoldenrod 0xAAE8EE +#define PaleGreen 0x98FB98 +#define PaleTurquoise 0xEEEEAF +#define PaleVioletRed 0x9370DB +#define PapayaWhip 0xD5EFFF +#define PeachPuff 0xB9DAFF +#define Peru 0x3F85CD +#define Pink 0xCBC0FF +#define Plum 0xDDA0DD +#define PowderBlue 0xE6E0B0 +#define Purple 0x800080 +#define Red 0x0000FF +#define RosyBrown 0x8F8FBC +#define RoyalBlue 0xE16941 +#define SaddleBrown 0x13458B +#define Salmon 0x7280FA +#define SandyBrown 0x60A4F4 +#define SeaGreen 0x578B2E +#define Seashell 0xEEF5FF +#define Sienna 0x2D52A0 +#define Silver 0xC0C0C0 +#define SkyBlue 0xEBCE87 +#define SlateBlue 0xCD5A6A +#define SlateGray 0x908070 +#define Snow 0xFAFAFF +#define SpringGreen 0x7FFF00 +#define SteelBlue 0xB48246 +#define Tan 0x8CB4D2 +#define Teal 0x808000 +#define Thistle 0xD8BFD8 +#define Tomato 0x4763FF +#define Turquoise 0xD0E040 +#define Violet 0xEE82EE +#define Wheat 0xB3DEF5 +#define White 0xFFFFFF +#define WhiteSmoke 0xF5F5F5 +#define Yellow 0x00FFFF +#define YellowGreen 0x32CD9A +#ifndef __MQL__ +#define clrNONE -1 +#define CLR_NONE -1 +#define DarkSeaGreen 0x8BBC8F +#endif + // Custom user errors. // @docs // - https://docs.mql4.com/common/setusererror @@ -37,6 +175,7 @@ #define ERR_USER_INVALID_HANDLE 4 #define ERR_USER_ITEM_NOT_FOUND 5 #define ERR_USER_NOT_SUPPORTED 6 +#define ERR_USER_ERROR_FIRST 65536 // User defined errors start with this code. // Return codes of the trade server. #define ERR_NO_ERROR 0 @@ -72,6 +211,46 @@ #define ERR_TRADE_HEDGE_PROHIBITED 149 #define ERR_TRADE_PROHIBITED_BY_FIFO 150 +#ifndef __MQL__ +// Return Codes of the Trade Server. +// @see: https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes +#define TRADE_RETCODE_REQUOTE 10004 // Requote +#define TRADE_RETCODE_REJECT 10006 // Request rejected +#define TRADE_RETCODE_CANCEL 10007 // Request canceled by trader +#define TRADE_RETCODE_PLACED 10008 // Order placed +#define TRADE_RETCODE_DONE 10009 // Request completed +#define TRADE_RETCODE_DONE_PARTIAL 10010 // Only part of the request was completed +#define TRADE_RETCODE_ERROR 10011 // Request processing error +#define TRADE_RETCODE_TIMEOUT 10012 // Request canceled by timeout +#define TRADE_RETCODE_INVALID 10013 // Invalid request +#define TRADE_RETCODE_INVALID_VOLUME 10014 // Invalid volume in the request +#define TRADE_RETCODE_INVALID_PRICE 10015 // Invalid price in the request +#define TRADE_RETCODE_INVALID_STOPS 10016 // Invalid stops in the request +#define TRADE_RETCODE_TRADE_DISABLED 10017 // Trade is disabled +#define TRADE_RETCODE_MARKET_CLOSED 10018 // Market is closed +#define TRADE_RETCODE_NO_MONEY 10019 // There is not enough money to complete the request +#define TRADE_RETCODE_PRICE_CHANGED 10020 // Prices changed +#define TRADE_RETCODE_PRICE_OFF 10021 // There are no quotes to process the request +#define TRADE_RETCODE_INVALID_EXPIRATION 10022 // Invalid order expiration date in the request +#define TRADE_RETCODE_ORDER_CHANGED 10023 // Order state changed +#define TRADE_RETCODE_TOO_MANY_REQUESTS 10024 // Too frequent requests +#define TRADE_RETCODE_NO_CHANGES 10025 // No changes in request +#define TRADE_RETCODE_SERVER_DISABLES_AT 10026 // Autotrading disabled by server +#define TRADE_RETCODE_CLIENT_DISABLES_AT 10027 // Autotrading disabled by client terminal +#define TRADE_RETCODE_LOCKED 10028 // Request locked for processing +#define TRADE_RETCODE_FROZEN 10029 // Order or position frozen +#define TRADE_RETCODE_INVALID_FILL 10030 // Invalid order filling type +#define TRADE_RETCODE_CONNECTION 10031 // No connection with the trade server +#define TRADE_RETCODE_ONLY_REAL 10032 // Operation is allowed only for live accounts +#define TRADE_RETCODE_LIMIT_ORDERS 10033 // The number of pending orders has reached the limit +#define TRADE_RETCODE_LIMIT_VOLUME 10034 // The volume of orders and positions for the symbol has reached the limit +#define TRADE_RETCODE_INVALID_ORDER 10035 // Incorrect or prohibited order type +#define TRADE_RETCODE_POSITION_CLOSED 10036 // Position with the specified POSITION_IDENTIFIER has already been closed +#define TRADE_RETCODE_INVALID_CLOSE_VOLUME 10038 // A close volume exceeds the current position volume +#define TRADE_RETCODE_CLOSE_ORDER_EXIST 10039 // A close order already exists. +#define TRADE_RETCODE_LIMIT_POSITIONS 10040 // The number of open positions can be limited (e.g. Netting, Hedging). +#endif + // Missing error handling constants in MQL4. // @see: https://docs.mql4.com/constants/errorswarnings/errorcodes // @see: https://www.mql5.com/en/docs/constants/errorswarnings From 19a1a845598377bc0c32e53cb9b27bc92f35952f Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 14:13:48 +0000 Subject: [PATCH 54/81] Adds .extern.h files --- Account.extern.h | 29 +++++++++++++++++++++++++++++ Array.extern.h | 31 +++++++++++++++++++++++++++++++ Common.extern.h | 33 +++++++++++++++++++++++++++++++++ Convert.extern.h | 28 ++++++++++++++++++++++++++++ File.extern.h | 36 ++++++++++++++++++++++++++++++++++++ Math.extern.h | 26 ++++++++++++++++++++++++++ String.extern.h | 33 +++++++++++++++++++++++++++++++++ SymbolInfo.extern.h | 37 +++++++++++++++++++++++++++++++++++++ Terminal.extern.h | 28 ++++++++++++++++++++++++++++ 9 files changed, 281 insertions(+) create mode 100644 Account.extern.h create mode 100644 Array.extern.h create mode 100644 Common.extern.h create mode 100644 Convert.extern.h create mode 100644 File.extern.h create mode 100644 Math.extern.h create mode 100644 String.extern.h create mode 100644 SymbolInfo.extern.h create mode 100644 Terminal.extern.h diff --git a/Account.extern.h b/Account.extern.h new file mode 100644 index 000000000..28aa8909d --- /dev/null +++ b/Account.extern.h @@ -0,0 +1,29 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Includes. +#include "Account.enum.h" + +// Define external global functions. +#ifndef __MQL__ +extern string AccountInfoString(ENUM_ACCOUNT_INFO_STRING property_id); +#endif diff --git a/Array.extern.h b/Array.extern.h new file mode 100644 index 000000000..cef60069d --- /dev/null +++ b/Array.extern.h @@ -0,0 +1,31 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern int ArrayInitialize(); +extern int ArrayResize(void& array[], int new_size, int reserve_size = 0); +extern bool ArrayReverse(); +extern bool ArraySetAsSeries(const void& array[], bool flag); +extern int ArraySize(const void& array[]); +extern bool ArraySort(void& array[]); +#endif diff --git a/Common.extern.h b/Common.extern.h new file mode 100644 index 000000000..71a526168 --- /dev/null +++ b/Common.extern.h @@ -0,0 +1,33 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern void PrintFormat(string format_string, ...); +// Exceptions. +extern int NotImplementedException(); +// Print() templates. +template +extern void Print(T arg); +template +extern void Print(T1 arg1, T2 arg2); +#endif diff --git a/Convert.extern.h b/Convert.extern.h new file mode 100644 index 000000000..2e92fdc30 --- /dev/null +++ b/Convert.extern.h @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern string CharToString(uchar char_code); +extern double NormalizeDouble(double value, int digits); +extern string DoubleToString(double value, int digits = 8); +#endif diff --git a/File.extern.h b/File.extern.h new file mode 100644 index 000000000..52e15849a --- /dev/null +++ b/File.extern.h @@ -0,0 +1,36 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Includes. +#include "File.define.h" +#include "Terminal.define.h" + +// Define external global functions. +#ifndef __MQL__ +extern bool FileIsEnding(int file_handle); +extern bool FileIsExist(const string file_name, int common_flag = 0); +extern int FileClose(int file_handle); +extern int FileOpen(string file_name, int open_flags, short delimiter = '\t', uint codepage = CP_ACP); +extern int FileReadInteger(int file_handle, int size = INT_VALUE); +extern string FileReadString(int file_handle, int length = -1); +extern uint FileWriteString(int file_handle, const string text_string, int length = -1); +#endif diff --git a/Math.extern.h b/Math.extern.h new file mode 100644 index 000000000..25b1d1705 --- /dev/null +++ b/Math.extern.h @@ -0,0 +1,26 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern double MathMax(double value1, double value2); +#endif diff --git a/String.extern.h b/String.extern.h new file mode 100644 index 000000000..8fdd275a9 --- /dev/null +++ b/String.extern.h @@ -0,0 +1,33 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern datetime StringToTime(const string time_string); +extern double StringToDouble(string value); +extern int StringLen(string string_value); +extern long StringToInteger(string value); +extern string IntegerToString(long number, int str_len = 0, ushort fill_symbol = ' '); +extern string StringFormat(string format, ...); +extern string StringSubstr(string string_value, int start_pos, int length = -1); +extern ushort StringGetCharacter(string string_value, int pos); +#endif diff --git a/SymbolInfo.extern.h b/SymbolInfo.extern.h new file mode 100644 index 000000000..1977cd3b0 --- /dev/null +++ b/SymbolInfo.extern.h @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Includes. +#include "MqlTick.h" +#include "Order.enum.h" +#include "SymbolInfo.enum.h" + +// Define external global functions. +#ifndef __MQL__ +extern long SymbolInfoInteger(string name, ENUM_SYMBOL_INFO_INTEGER prop_id); +extern bool SymbolInfoMarginRate(string name, ENUM_ORDER_TYPE order_type, double &initial_margin_rate, + double &maintenance_margin_rate); +extern bool SymbolInfoTick(string symbol, MqlTick &tick); + +// Define external global variables. +extern string _Symbol; +#endif diff --git a/Terminal.extern.h b/Terminal.extern.h new file mode 100644 index 000000000..65582439f --- /dev/null +++ b/Terminal.extern.h @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Define external global functions. +#ifndef __MQL__ +extern int GetLastError(); +extern string TerminalInfoString(int property_id); +extern void ResetLastError(); +#endif From 79e542c4a45930ab6264080fedcf1833a6774b8f Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 14:13:59 +0000 Subject: [PATCH 55/81] Adds code page defines --- Terminal.define.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Terminal.define.h b/Terminal.define.h index ef833c2da..9b03a7398 100644 --- a/Terminal.define.h +++ b/Terminal.define.h @@ -27,6 +27,16 @@ /* Defines */ +// Codepages. +// @see: https://www.mql5.com/en/docs/constants/io_constants/codepageusage +#define CP_ACP 0 // The current Windows ANSI code page. +#define CP_OEMCP 1 // The current system OEM code page. +#define CP_MACCP 2 // The current system Macintosh code page. +#define CP_THREAD_ACP 3 // The Windows ANSI code page for the current thread. +#define CP_SYMBOL 42 // Symbol code page +#define CP_UTF7 65000 // UTF-7 code page. +#define CP_UTF8 65001 // UTF-8 code page. + // Colors. #define AliceBlue 0xFFF8F0 #define AntiqueWhite 0xD7EBFA From df9180d01cef33597779657ece74a46834ab80da Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 14:14:51 +0000 Subject: [PATCH 56/81] Adds Common and File defines --- Common.define.h | 36 ++++++++++++++++++++++++++++++++++++ File.define.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 Common.define.h create mode 100644 File.define.h diff --git a/Common.define.h b/Common.define.h new file mode 100644 index 000000000..c12649130 --- /dev/null +++ b/Common.define.h @@ -0,0 +1,36 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Defines common defines. + */ +#ifndef __MQL__ +// Data types. +typedef std::string string; +typedef unsigned char uchar +typedef unsigned int uint; +typedef unsigned long datetime; +typedef unsigned long ulong; +typedef unsigned short ushort; +#endif diff --git a/File.define.h b/File.define.h new file mode 100644 index 000000000..e932ab836 --- /dev/null +++ b/File.define.h @@ -0,0 +1,31 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Defines. +#ifndef __MQL__ +// File constants to read the whole value of char, short or int type. +#define CHAR_VALUE 1 +#define INT_VALUE 4 +#define SHORT_VALUE 2 +// Used for checking file handles (see FileOpen() and FileFindFirst()). +#define INVALID_HANDLE -1 +#endif From a70c3587b36fab913ec1c927e736315fae9e9200 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 14:15:20 +0000 Subject: [PATCH 57/81] Integrates extern includes --- Account.mqh | 1 + Array.mqh | 8 ++++++-- Common.define.h | 3 +-- Common.extern.h | 1 + Convert.extern.h | 5 +++++ Convert.mqh | 9 ++++++--- File.mqh | 3 +++ Math.h | 1 + Object.enum.h | 38 ++++++++++++++++++++++++++++++++++++++ Object.mqh | 13 +------------ String.mqh | 1 + SymbolInfo.mqh | 1 + Terminal.mqh | 1 + 13 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 Object.enum.h diff --git a/Account.mqh b/Account.mqh index 737b62f28..cafd14e4c 100644 --- a/Account.mqh +++ b/Account.mqh @@ -30,6 +30,7 @@ class Account; // Includes. #include "Account.define.h" #include "Account.enum.h" +#include "Account.extern.h" #include "Account.struct.h" #include "Array.mqh" #include "BufferStruct.mqh" diff --git a/Array.mqh b/Array.mqh index 0a8a08635..c8e549170 100644 --- a/Array.mqh +++ b/Array.mqh @@ -26,6 +26,10 @@ #endif // Includes. +#include "Array.extern.h" +#include "Convert.extern.h" +#include "Common.extern.h" +#include "Math.extern.h" #include "Std.h" // Defines. @@ -529,7 +533,7 @@ static int GetLowestArrDoubleValue(double& arr[][], int key) { */ template void ArrayPrint(ARRAY_REF(T, _arr), // Printed array. - int _digits = NULL, // Number of decimal places. + int _digits = 0, // Number of decimal places. const string _dlm = NULL, // Separator of the structure field values. long _start = 0, // First printed element index. long _count = WHOLE_ARRAY, // Number of printed elements. @@ -635,7 +639,7 @@ static int GetLowestArrDoubleValue(double& arr[][], int key) { * if error occured). */ template - static int ArrayResizeFill(ARRAY_REF(X, array), int new_size, int reserve_size = 0, Y fill_value = EMPTY_VALUE) { + static int ArrayResizeFill(ARRAY_REF(X, array), int new_size, int reserve_size = 0, Y fill_value = NULL) { const int old_size = ArrayRange(array, 0); if (new_size <= old_size) return old_size; diff --git a/Common.define.h b/Common.define.h index c12649130..c799d9921 100644 --- a/Common.define.h +++ b/Common.define.h @@ -20,7 +20,6 @@ * */ - /** * @file * Defines common defines. @@ -28,7 +27,7 @@ #ifndef __MQL__ // Data types. typedef std::string string; -typedef unsigned char uchar +typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long datetime; typedef unsigned long ulong; diff --git a/Common.extern.h b/Common.extern.h index 71a526168..974a579f9 100644 --- a/Common.extern.h +++ b/Common.extern.h @@ -22,6 +22,7 @@ // Define external global functions. #ifndef __MQL__ +extern void DebugBreak(); extern void PrintFormat(string format_string, ...); // Exceptions. extern int NotImplementedException(); diff --git a/Convert.extern.h b/Convert.extern.h index 2e92fdc30..2a09773b0 100644 --- a/Convert.extern.h +++ b/Convert.extern.h @@ -20,6 +20,11 @@ * */ +// Prevents processing this includes file for the second time. +#ifndef __MQL__ +#pragma once +#endif + // Define external global functions. #ifndef __MQL__ extern string CharToString(uchar char_code); diff --git a/Convert.mqh b/Convert.mqh index 072f8b6b2..50d81fbd2 100644 --- a/Convert.mqh +++ b/Convert.mqh @@ -26,9 +26,12 @@ // Includes. #include "Account.enum.h" +#include "Account.extern.h" #include "Array.mqh" +#include "Convert.extern.h" #include "Order.enum.h" #include "SymbolInfo.enum.h" +#include "SymbolInfo.extern.h" #include "SymbolInfo.static.h" /** @@ -58,7 +61,7 @@ class Convert { case ORDER_TYPE_BUY_STOP: return ORDER_TYPE_BUY; default: - return (ENUM_ORDER_TYPE)WRONG_VALUE; + return (ENUM_ORDER_TYPE)-1; } } @@ -243,7 +246,7 @@ class Convert { /** * Get the difference between two price values (in pips). */ - static double GetValueDiffInPips(double price1, double price2, bool abs = false, int digits = NULL, + static double GetValueDiffInPips(double price1, double price2, bool abs = false, int digits = 0, string _symbol = NULL) { digits = digits ? digits : (int)SymbolInfoStatic::SymbolInfoInteger(_symbol, SYMBOL_DIGITS); return ValueToPips(abs ? fabs(price1 - price2) : (price1 - price2), digits); @@ -263,7 +266,7 @@ class Convert { else if (currency == "EUR") sign = (unsigned char)0x80; // ANSI code. else { - sign = NULL; + sign = ' '; prefix = false; } return prefix ? CharToString(sign) + DoubleToString(value, digits) diff --git a/File.mqh b/File.mqh index 4fe3dcb6b..56c33bd57 100644 --- a/File.mqh +++ b/File.mqh @@ -30,7 +30,10 @@ */ // Includes. +#include "File.define.h" +#include "File.extern.h" #include "Terminal.define.h" +#include "Terminal.extern.h" #include "Terminal.enum.h" #ifndef __MQL__ diff --git a/Math.h b/Math.h index 4edd25801..691837b31 100644 --- a/Math.h +++ b/Math.h @@ -30,6 +30,7 @@ #include "Indicator.struct.h" #include "Math.define.h" #include "Math.enum.h" +#include "Math.extern.h" #include "Math.struct.h" /** diff --git a/Object.enum.h b/Object.enum.h new file mode 100644 index 000000000..68d22f513 --- /dev/null +++ b/Object.enum.h @@ -0,0 +1,38 @@ +//+------------------------------------------------------------------+ +//| EA31337 - multi-strategy advanced trading robot. | +//| Copyright 2016-2022, 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 + * Includes enumerations used for objects. + */ + +#ifndef __MQLBUILD__ +// Used for checking the type of the object pointer. +// @docs +// - https://docs.mql4.com/constants/namedconstants/enum_pointer_type +// - https://www.mql5.com/en/docs/constants/namedconstants/enum_pointer_type +enum ENUM_POINTER_TYPE { + POINTER_INVALID, // Incorrect pointer. + POINTER_DYNAMIC, // Pointer of the object created by the new() operator. + POINTER_AUTOMATIC // Pointer of any objects created automatically (not using new()). +}; +#endif diff --git a/Object.mqh b/Object.mqh index 36f69ec28..d711500d8 100644 --- a/Object.mqh +++ b/Object.mqh @@ -25,21 +25,10 @@ #define OBJECT_MQH // Includes. +#include "Object.enum.h" #include "Refs.mqh" #include "String.mqh" -#ifndef __MQLBUILD__ -// Used for checking the type of the object pointer. -// @docs -// - https://docs.mql4.com/constants/namedconstants/enum_pointer_type -// - https://www.mql5.com/en/docs/constants/namedconstants/enum_pointer_type -enum ENUM_POINTER_TYPE { - POINTER_INVALID, // Incorrect pointer. - POINTER_DYNAMIC, // Pointer of the object created by the new() operator. - POINTER_AUTOMATIC // Pointer of any objects created automatically (not using new()). -}; -#endif - /** * Class to deal with objects. */ diff --git a/String.mqh b/String.mqh index 3acccfd30..f8a4d18f6 100644 --- a/String.mqh +++ b/String.mqh @@ -26,6 +26,7 @@ // Includes. #include "Std.h" +#include "String.extern.h" // Defines. #define NL "\n" // New line: 0x0A (MQL file functions auto-convert 0x0A to 0x0D0A). diff --git a/SymbolInfo.mqh b/SymbolInfo.mqh index d4f1957ec..735d24271 100644 --- a/SymbolInfo.mqh +++ b/SymbolInfo.mqh @@ -31,6 +31,7 @@ class SymbolInfo; #include "SymbolInfo.define.h" #include "SymbolInfo.enum.h" #include "SymbolInfo.enum.symbols.h" +#include "SymbolInfo.extern.h" #include "SymbolInfo.static.h" #include "SymbolInfo.struct.h" diff --git a/Terminal.mqh b/Terminal.mqh index d408480a3..77aa28d13 100644 --- a/Terminal.mqh +++ b/Terminal.mqh @@ -43,6 +43,7 @@ class Terminal; #include "Refs.mqh" #include "String.mqh" #include "Terminal.define.h" +#include "Terminal.extern.h" #include "Terminal.enum.h" #include "Terminal.struct.h" From c3bb151d12c9a091a5ae8479c16f72f00127f328 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 14:51:17 +0000 Subject: [PATCH 58/81] Refs: Uses PTR_ATTRIB syntax --- Object.extern.h | 30 ++++++++++++++++++++++++++++++ Object.mqh | 1 + Refs.struct.h | 41 ++++++++++++++++++++++------------------- Std.h | 14 ++------------ 4 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 Object.extern.h diff --git a/Object.extern.h b/Object.extern.h new file mode 100644 index 000000000..14d09dac0 --- /dev/null +++ b/Object.extern.h @@ -0,0 +1,30 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Includes external declarations related to objects. + */ +#ifndef __MQL__ +extern void *GetPointer(void *anyobject); +#endif diff --git a/Object.mqh b/Object.mqh index d711500d8..86897917a 100644 --- a/Object.mqh +++ b/Object.mqh @@ -26,6 +26,7 @@ // Includes. #include "Object.enum.h" +#include "Object.extern.h" #include "Refs.mqh" #include "String.mqh" diff --git a/Refs.struct.h b/Refs.struct.h index e244a7c93..dc473df3b 100644 --- a/Refs.struct.h +++ b/Refs.struct.h @@ -30,9 +30,12 @@ #pragma once #endif +// Includes. +#include "Std.h" + // Forward class declaration. class Refs; -class ReferenceCounter; +//class ReferenceCounter; template struct WeakRef; @@ -140,19 +143,19 @@ struct Ref { ptr_object = NULL; return; } - if (ptr_object.ptr_ref_counter == NULL) { + if (PTR_ATTRIB(ptr_object, ptr_ref_counter) == NULL) { // Object is not reference counted. Maybe a stack-based one? return; } // Dropping strong reference. - if (!--ptr_object.ptr_ref_counter.num_strong_refs) { + if (!--PTR_ATTRIB2(ptr_object, ptr_ref_counter, num_strong_refs)) { #ifdef __debug__ Print(ptr_object.ptr_ref_counter.Debug()); #endif // No more strong references. - if (!ptr_object.ptr_ref_counter.num_weak_refs) { - if (CheckPointer(ptr_object.ptr_ref_counter) == POINTER_INVALID) { + if (!PTR_ATTRIB2(ptr_object, ptr_ref_counter, num_weak_refs)) { + if (CheckPointer(PTR_ATTRIB(ptr_object, ptr_ref_counter)) == POINTER_INVALID) { // Serious problem. #ifndef __MQL4__ // Bug: Avoid calling in MQL4 due to 'global initialization failed' error. @@ -162,11 +165,11 @@ struct Ref { } // Also no more weak references. - delete ptr_object.ptr_ref_counter; - ptr_object.ptr_ref_counter = NULL; + delete PTR_ATTRIB(ptr_object, ptr_ref_counter); + PTR_ATTRIB(ptr_object, ptr_ref_counter) = NULL; } else { // Object becomes deleted, but there are some weak references. - ptr_object.ptr_ref_counter.deleted = true; + PTR_ATTRIB(PTR_ATTRIB(ptr_object, ptr_ref_counter), deleted) = true; } // Avoiding delete loop for cyclic references. @@ -182,7 +185,7 @@ struct Ref { } // Avoiding double deletion in Dynamic's destructor. - ptr_object.ptr_ref_counter = NULL; + PTR_ATTRIB(ptr_object, ptr_ref_counter) = NULL; ptr_object = NULL; delete ptr_to_delete; @@ -206,11 +209,11 @@ struct Ref { ptr_object = _ptr; if (ptr_object != NULL) { - if (CheckPointer(ptr_object) == POINTER_INVALID || ptr_object.ptr_ref_counter == NULL) { + if (CheckPointer(ptr_object) == POINTER_INVALID || PTR_ATTRIB(ptr_object, ptr_ref_counter) == NULL) { // Double check the pointer for invalid references. Can happen very rarely. return; } - ++ptr_object.ptr_ref_counter.num_strong_refs; + ++PTR_ATTRIB(PTR_ATTRIB(ptr_object, ptr_ref_counter), num_strong_refs); #ifdef __debug__ Print(ptr_object.ptr_ref_counter.Debug()); #endif @@ -259,15 +262,15 @@ struct WeakRef { */ ~WeakRef() { Unset(); } - bool ObjectExists() { return ptr_ref_counter != NULL && !ptr_ref_counter.deleted; } + bool ObjectExists() { return ptr_ref_counter != NULL && !PTR_ATTRIB(ptr_ref_counter, deleted); } - X* Ptr() { return ObjectExists() ? (X*)ptr_ref_counter.ptr_object : NULL; } + X* Ptr() { return ObjectExists() ? (X*)PTR_ATTRIB(ptr_ref_counter, ptr_object) : NULL; } /** * Makes a strong reference to the given object. */ void operator=(X* _ptr) { - if (ptr_ref_counter == (_ptr == NULL ? NULL : _ptr.ptr_ref_counter)) { + if (ptr_ref_counter == (_ptr == NULL ? NULL : PTR_ATTRIB(_ptr, ptr_ref_counter))) { // Assigning the same object or the same NULL. return; } @@ -279,19 +282,19 @@ struct WeakRef { return; } - if (_ptr.ptr_ref_counter.deleted) { + if (PTR_ATTRIB2(_ptr, ptr_ref_counter, deleted)) { // Assigning already deleted object. ptr_ref_counter = NULL; return; } - ptr_ref_counter = _ptr.ptr_ref_counter; + ptr_ref_counter = PTR_ATTRIB(_ptr, ptr_ref_counter); #ifdef __debug__ Print(ptr_ref_counter.Debug()); #endif - ++ptr_ref_counter.num_weak_refs; + ++PTR_ATTRIB(ptr_ref_counter, num_weak_refs); } /** @@ -310,13 +313,13 @@ struct WeakRef { void Unset() { if (ptr_ref_counter != NULL) { // Dropping weak reference. - if (!--ptr_ref_counter.num_weak_refs) { + if (!--PTR_ATTRIB(ptr_ref_counter, num_weak_refs)) { // No more weak references. #ifdef __debug__ Print(ptr_ref_counter.Debug()); #endif - if (!ptr_ref_counter.num_strong_refs) { + if (!PTR_ATTRIB(ptr_ref_counter, num_strong_refs)) { // There are also no strong references. ReferenceCounter* stored_ptr_ref_counter = ptr_ref_counter; if (!ptr_ref_counter.deleted) { diff --git a/Std.h b/Std.h index 22a6318e3..642b44237 100644 --- a/Std.h +++ b/Std.h @@ -31,13 +31,6 @@ #include #include #include - -// Data types. -typedef std::string string; -typedef unsigned int uint; -typedef unsigned long datetime; -typedef unsigned long ulong; -typedef unsigned short ushort; #endif #ifdef __MQL__ @@ -51,12 +44,14 @@ typedef unsigned short ushort; #define THIS_PTR (&this) #define THIS_REF this #define PTR_ATTRIB(O, A) O.A +#define PTR_ATTRIB2(O, A, B) O.A.B #define PTR_TO_REF(PTR) PTR #define MAKE_REF_FROM_PTR(TYPE, NAME, PTR) TYPE* NAME = PTR #else #define THIS_PTR (this) #define THIS_REF (*this) #define PTR_ATTRIB(O, A) O->A +#define PTR_ATTRIB2(O, A, B) O->A->B #define PTR_TO_REF(PTR) (*PTR) #define MAKE_REF_FROM_PTR(TYPE, NAME, PTR) TYPE& NAME = PTR #endif @@ -191,11 +186,6 @@ class color { }; #endif -// GetPointer(ptr). -#ifndef __MQL__ -unsigned int GetPointer(void* _ptr) { return (unsigned int)_ptr; } -#endif - // MQL defines. #ifndef __MQL__ #define WHOLE_ARRAY -1 // For processing the entire array. From 871cc70c2a48348b4d04f0ac26c972cd7cab7dc8 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 18 Jan 2022 16:20:23 +0100 Subject: [PATCH 59/81] Fixed order of mode and shift when calling Indicator::GetValue(). Sometimes mode and shift was misordered. --- IndicatorBase.h | 4 ++-- Indicators/Bitwise/Indi_Candle.mqh | 8 ++++---- Indicators/Bitwise/Indi_Pattern.mqh | 8 ++++---- Indicators/Indi_Pivot.mqh | 8 ++++---- Indicators/Special/Indi_Math.mqh | 8 ++++---- Storage/ValueStorage.indicator.h | 2 +- tests/IndicatorTest.mq5 | 10 +++++----- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/IndicatorBase.h b/IndicatorBase.h index d1f61d607..a5c35282f 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -424,9 +424,9 @@ class IndicatorBase : public Chart { } template - T GetValue(int _index = 0, int _mode = 0) { + T GetValue(int _mode = 0, int _index = 0) { T _out; - GetEntryValue(_index, _mode).Get(_out); + GetEntryValue(_mode, _index).Get(_out); return _out; } diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index a9b94aea1..d24d3eeb9 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -93,10 +93,10 @@ class Indi_Candle : public Indicator { break; } - _ohlcs[0].open = GetDataSource().GetValue(_ishift, PRICE_OPEN); - _ohlcs[0].high = GetDataSource().GetValue(_ishift, PRICE_HIGH); - _ohlcs[0].low = GetDataSource().GetValue(_ishift, PRICE_LOW); - _ohlcs[0].close = GetDataSource().GetValue(_ishift, PRICE_CLOSE); + _ohlcs[0].open = GetDataSource().GetValue(PRICE_OPEN, _ishift); + _ohlcs[0].high = GetDataSource().GetValue(PRICE_HIGH, _ishift); + _ohlcs[0].low = GetDataSource().GetValue(PRICE_LOW, _ishift); + _ohlcs[0].close = GetDataSource().GetValue(PRICE_CLOSE, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index f9e014ec0..62e1b1a60 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -91,10 +91,10 @@ class Indi_Pattern : public Indicator { } for (i = 0; i < iparams.GetMaxModes(); ++i) { - _ohlcs[i].open = GetDataSource().GetValue(_ishift + i, PRICE_OPEN); - _ohlcs[i].high = GetDataSource().GetValue(_ishift + i, PRICE_HIGH); - _ohlcs[i].low = GetDataSource().GetValue(_ishift + i, PRICE_LOW); - _ohlcs[i].close = GetDataSource().GetValue(_ishift + i, PRICE_CLOSE); + _ohlcs[i].open = GetDataSource().GetValue(PRICE_OPEN, _ishift + i); + _ohlcs[i].high = GetDataSource().GetValue(PRICE_HIGH, _ishift + i); + _ohlcs[i].low = GetDataSource().GetValue(PRICE_LOW, _ishift + i); + _ohlcs[i].close = GetDataSource().GetValue(PRICE_CLOSE, _ishift + i); if (!_ohlcs[i].IsValid()) { // Return empty entry on invalid candles. return WRONG_VALUE; diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index fd4c7cf4d..50e776a7d 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -148,10 +148,10 @@ class Indi_Pivot : public Indicator { // must have at least 4 buffers and define OHLC in the first 4 buffers. // Indi_Price is an example of such indicator. if (HasDataSource()) { - _ohlc.open = GetDataSource().GetValue(_shift, PRICE_OPEN); - _ohlc.high = GetDataSource().GetValue(_shift, PRICE_HIGH); - _ohlc.low = GetDataSource().GetValue(_shift, PRICE_LOW); - _ohlc.close = GetDataSource().GetValue(_shift, PRICE_CLOSE); + _ohlc.open = GetDataSource().GetValue(PRICE_OPEN, _shift); + _ohlc.high = GetDataSource().GetValue(PRICE_HIGH, _shift); + _ohlc.low = GetDataSource().GetValue(PRICE_LOW, _shift); + _ohlc.close = GetDataSource().GetValue(PRICE_CLOSE, _shift); } break; default: diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index 033377c04..5b13f1227 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -132,16 +132,16 @@ class Indi_Math : public Indicator { static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_MATH_OP op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { - double _val_1 = _indi.GetValue(_shift_1, _mode_1); - double _val_2 = _indi.GetValue(_shift_2, _mode_2); + double _val_1 = _indi.GetValue(_mode_1, _shift_1); + double _val_2 = _indi.GetValue(_mode_2, _shift_2); return Math::Op(op, _val_1, _val_2); } static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, MathCustomOpFunction _op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { - double _val_1 = _indi.GetValue(_shift_1, _mode_1); - double _val_2 = _indi.GetValue(_shift_2, _mode_2); + double _val_1 = _indi.GetValue(_mode_1, _shift_1); + double _val_2 = _indi.GetValue(_mode_2, _shift_2); return _op(_val_1, _val_2); } diff --git a/Storage/ValueStorage.indicator.h b/Storage/ValueStorage.indicator.h index 4dc6aacb0..e363559b2 100644 --- a/Storage/ValueStorage.indicator.h +++ b/Storage/ValueStorage.indicator.h @@ -57,5 +57,5 @@ class IndicatorBufferValueStorage : public HistoryValueStorage { /** * Fetches value from a given shift. Takes into consideration as-series flag. */ - virtual C Fetch(int _shift) { return indicator.GetValue(RealShift(_shift), mode); } + virtual C Fetch(int _shift) { return indicator.GetValue(mode, RealShift(_shift)); } }; diff --git a/tests/IndicatorTest.mq5 b/tests/IndicatorTest.mq5 index fde4800ce..79b70758c 100644 --- a/tests/IndicatorTest.mq5 +++ b/tests/IndicatorTest.mq5 @@ -45,14 +45,14 @@ int OnInit() { entry.integer_value = 1; for (uint i = 0; i < in.GetBufferSize() * 2; i++) { in.AddValue(entry); - Print("Index ", i, ": Curr: ", in.GetValue(0).integer_value, "; Prev: ", in.GetValue(1).integer_value); - assertTrueOrFail(in.GetValue(0).integer_value == entry.integer_value, + Print("Index ", i, ": Curr: ", in.GetValue(0, 0).integer_value, "; Prev: ", in.GetValue(0, 1).integer_value); + assertTrueOrFail(in.GetValue(0, 0).integer_value == entry.integer_value, StringFormat("Wrong latest value (%d <> %d)!", - in.GetValue(0).integer_value, + in.GetValue(0, 0).integer_value, entry.integer_value)); - assertTrueOrFail(in.GetValue(1).integer_value == entry.integer_value - 1, + assertTrueOrFail(in.GetValue(0, 1).integer_value == entry.integer_value - 1, StringFormat("Wrong previous value (%d <> %d)!", - in.GetValue(1).integer_value, + in.GetValue(0, 1).integer_value, entry.integer_value - 1)); entry.integer_value++; } From fde05e4fca68b287a62a93c0eae447184dad717e Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 15:34:18 +0000 Subject: [PATCH 60/81] Adds .extern.h file for DateTime --- DateTime.extern.h | 32 ++++++++++++++++++++++++++++++++ DateTime.mqh | 1 + SerializerConversions.h | 1 + 3 files changed, 34 insertions(+) create mode 100644 DateTime.extern.h diff --git a/DateTime.extern.h b/DateTime.extern.h new file mode 100644 index 000000000..bbf533ed2 --- /dev/null +++ b/DateTime.extern.h @@ -0,0 +1,32 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 . + * + */ + +// Includes. +#include "DateTime.enum.h" + +/** + * @file + * Includes external declarations related to date and time. + */ +#ifndef __MQL__ +extern string TimeToString(datetime value, int mode=TIME_DATE|TIME_MINUTES); +#endif diff --git a/DateTime.mqh b/DateTime.mqh index 49502d55f..c081d0d44 100644 --- a/DateTime.mqh +++ b/DateTime.mqh @@ -40,6 +40,7 @@ struct DataParamEntry; #include "Array.mqh" #include "Data.struct.h" #include "DateTime.enum.h" +#include "DateTime.extern.h" #include "DateTime.struct.h" #ifndef __MQL4__ diff --git a/SerializerConversions.h b/SerializerConversions.h index eaea26bd0..8ca443963 100644 --- a/SerializerConversions.h +++ b/SerializerConversions.h @@ -30,6 +30,7 @@ #pragma once #endif +#include "DateTime.extern.h" #include "Object.mqh" #include "Refs.struct.h" From 471e417faf209ba2b2bd08bfcdd395c172cf74f4 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 15:41:46 +0000 Subject: [PATCH 61/81] Adds StringSplit() as extern --- Convert.extern.h | 3 ++- DateTime.extern.h | 2 +- Object.extern.h | 1 - String.extern.h | 6 ++++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Convert.extern.h b/Convert.extern.h index 2a09773b0..353a96b6b 100644 --- a/Convert.extern.h +++ b/Convert.extern.h @@ -27,7 +27,8 @@ // Define external global functions. #ifndef __MQL__ -extern string CharToString(uchar char_code); extern double NormalizeDouble(double value, int digits); +extern string CharToString(uchar char_code); extern string DoubleToString(double value, int digits = 8); +extern string ShortToString(ushort symbol_code); #endif diff --git a/DateTime.extern.h b/DateTime.extern.h index bbf533ed2..11e1d0ad8 100644 --- a/DateTime.extern.h +++ b/DateTime.extern.h @@ -28,5 +28,5 @@ * Includes external declarations related to date and time. */ #ifndef __MQL__ -extern string TimeToString(datetime value, int mode=TIME_DATE|TIME_MINUTES); +extern string TimeToString(datetime value, int mode = TIME_DATE | TIME_MINUTES); #endif diff --git a/Object.extern.h b/Object.extern.h index 14d09dac0..f8b97dbd8 100644 --- a/Object.extern.h +++ b/Object.extern.h @@ -20,7 +20,6 @@ * */ - /** * @file * Includes external declarations related to objects. diff --git a/String.extern.h b/String.extern.h index 8fdd275a9..ee7943b96 100644 --- a/String.extern.h +++ b/String.extern.h @@ -20,11 +20,17 @@ * */ +// Prevents processing this includes file for the second time. +#ifndef __MQL__ +#pragma once +#endif + // Define external global functions. #ifndef __MQL__ extern datetime StringToTime(const string time_string); extern double StringToDouble(string value); extern int StringLen(string string_value); +extern int StringSplit(const string string_value, const ushort separator, string &result[]); extern long StringToInteger(string value); extern string IntegerToString(long number, int str_len = 0, ushort fill_symbol = ' '); extern string StringFormat(string format, ...); From f2142ea84fa0485afb4f8e86fd1dd19f572e305c Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 16:02:11 +0000 Subject: [PATCH 62/81] Adds Compile workflow for CPP --- .github/workflows/compile-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/compile-cpp.yml diff --git a/.github/workflows/compile-cpp.yml b/.github/workflows/compile-cpp.yml new file mode 100644 index 000000000..3e075f51c --- /dev/null +++ b/.github/workflows/compile-cpp.yml @@ -0,0 +1,23 @@ +--- +name: Compile C++ + +# yamllint disable-line rule:truthy +on: + pull_request: + paths-ignore: + - '**.md' + push: + paths-ignore: + - '**.md' + +jobs: + + Compile: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install compiler + uses: rlalik/setup-cpp-compiler@v1.1 + with: + compiler: gcc-latest + - run: g++ --version From 8e39201f4eb4cb546b529122ec543b0cd33450f5 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 18 Jan 2022 16:20:23 +0100 Subject: [PATCH 63/81] Fixed order of mode and shift when calling Indicator::GetValue(). Sometimes mode and shift was misordered. --- IndicatorBase.h | 2 +- Indicators/Bitwise/Indi_Candle.mqh | 8 ++++---- Indicators/Bitwise/Indi_Pattern.mqh | 8 ++++---- Indicators/Indi_Pivot.mqh | 8 ++++---- Indicators/Special/Indi_Math.mqh | 8 ++++---- Storage/ValueStorage.indicator.h | 2 +- tests/IndicatorTest.mq5 | 10 +++++----- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/IndicatorBase.h b/IndicatorBase.h index 6e5ec56b4..4feceb40d 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -565,7 +565,7 @@ class IndicatorBase : public Chart { virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { return false; } template - T GetValue(int _index = 0, int _mode = 0) { + T GetValue(int _mode = 0, int _index = 0) { T _out; GetEntryValue(_mode, _index).Get(_out); return _out; diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 13c98aeed..3171251f7 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -94,10 +94,10 @@ class Indi_Candle : public IndicatorTickOrCandleSource { break; } - _ohlcs[0].open = GetDataSource().GetValue(_ishift, PRICE_OPEN); - _ohlcs[0].high = GetDataSource().GetValue(_ishift, PRICE_HIGH); - _ohlcs[0].low = GetDataSource().GetValue(_ishift, PRICE_LOW); - _ohlcs[0].close = GetDataSource().GetValue(_ishift, PRICE_CLOSE); + _ohlcs[0].open = GetDataSource().GetValue(PRICE_OPEN, _ishift); + _ohlcs[0].high = GetDataSource().GetValue(PRICE_HIGH, _ishift); + _ohlcs[0].low = GetDataSource().GetValue(PRICE_LOW, _ishift); + _ohlcs[0].close = GetDataSource().GetValue(PRICE_CLOSE, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index 1e13c4217..dc5bdc958 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -92,10 +92,10 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { } for (i = 0; i < iparams.GetMaxModes(); ++i) { - _ohlcs[i].open = GetDataSource().GetValue(_ishift + i, PRICE_OPEN); - _ohlcs[i].high = GetDataSource().GetValue(_ishift + i, PRICE_HIGH); - _ohlcs[i].low = GetDataSource().GetValue(_ishift + i, PRICE_LOW); - _ohlcs[i].close = GetDataSource().GetValue(_ishift + i, PRICE_CLOSE); + _ohlcs[i].open = GetDataSource().GetValue(PRICE_OPEN, _ishift + i); + _ohlcs[i].high = GetDataSource().GetValue(PRICE_HIGH, _ishift + i); + _ohlcs[i].low = GetDataSource().GetValue(PRICE_LOW, _ishift + i); + _ohlcs[i].close = GetDataSource().GetValue(PRICE_CLOSE, _ishift + i); if (!_ohlcs[i].IsValid()) { // Return empty entry on invalid candles. return WRONG_VALUE; diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index c4c785be6..75a737974 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -149,10 +149,10 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { // must have at least 4 buffers and define OHLC in the first 4 buffers. // Indi_Price is an example of such indicator. if (HasDataSource()) { - _ohlc.open = GetDataSource().GetValue(_shift, PRICE_OPEN); - _ohlc.high = GetDataSource().GetValue(_shift, PRICE_HIGH); - _ohlc.low = GetDataSource().GetValue(_shift, PRICE_LOW); - _ohlc.close = GetDataSource().GetValue(_shift, PRICE_CLOSE); + _ohlc.open = GetDataSource().GetValue(PRICE_OPEN, _shift); + _ohlc.high = GetDataSource().GetValue(PRICE_HIGH, _shift); + _ohlc.low = GetDataSource().GetValue(PRICE_LOW, _shift); + _ohlc.close = GetDataSource().GetValue(PRICE_CLOSE, _shift); } break; default: diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index eaacecca5..098b4fc3f 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -133,16 +133,16 @@ class Indi_Math : public IndicatorTickOrCandleSource { static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_MATH_OP op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { - double _val_1 = _indi.GetValue(_shift_1, _mode_1); - double _val_2 = _indi.GetValue(_shift_2, _mode_2); + double _val_1 = _indi.GetValue(_mode_1, _shift_1); + double _val_2 = _indi.GetValue(_mode_2, _shift_2); return Math::Op(op, _val_1, _val_2); } static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, MathCustomOpFunction _op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { - double _val_1 = _indi.GetValue(_shift_1, _mode_1); - double _val_2 = _indi.GetValue(_shift_2, _mode_2); + double _val_1 = _indi.GetValue(_mode_1, _shift_1); + double _val_2 = _indi.GetValue(_mode_2, _shift_2); return _op(_val_1, _val_2); } diff --git a/Storage/ValueStorage.indicator.h b/Storage/ValueStorage.indicator.h index 4dc6aacb0..e363559b2 100644 --- a/Storage/ValueStorage.indicator.h +++ b/Storage/ValueStorage.indicator.h @@ -57,5 +57,5 @@ class IndicatorBufferValueStorage : public HistoryValueStorage { /** * Fetches value from a given shift. Takes into consideration as-series flag. */ - virtual C Fetch(int _shift) { return indicator.GetValue(RealShift(_shift), mode); } + virtual C Fetch(int _shift) { return indicator.GetValue(mode, RealShift(_shift)); } }; diff --git a/tests/IndicatorTest.mq5 b/tests/IndicatorTest.mq5 index fde4800ce..79b70758c 100644 --- a/tests/IndicatorTest.mq5 +++ b/tests/IndicatorTest.mq5 @@ -45,14 +45,14 @@ int OnInit() { entry.integer_value = 1; for (uint i = 0; i < in.GetBufferSize() * 2; i++) { in.AddValue(entry); - Print("Index ", i, ": Curr: ", in.GetValue(0).integer_value, "; Prev: ", in.GetValue(1).integer_value); - assertTrueOrFail(in.GetValue(0).integer_value == entry.integer_value, + Print("Index ", i, ": Curr: ", in.GetValue(0, 0).integer_value, "; Prev: ", in.GetValue(0, 1).integer_value); + assertTrueOrFail(in.GetValue(0, 0).integer_value == entry.integer_value, StringFormat("Wrong latest value (%d <> %d)!", - in.GetValue(0).integer_value, + in.GetValue(0, 0).integer_value, entry.integer_value)); - assertTrueOrFail(in.GetValue(1).integer_value == entry.integer_value - 1, + assertTrueOrFail(in.GetValue(0, 1).integer_value == entry.integer_value - 1, StringFormat("Wrong previous value (%d <> %d)!", - in.GetValue(1).integer_value, + in.GetValue(0, 1).integer_value, entry.integer_value - 1)); entry.integer_value++; } From 71108dc08f7769469f0ea7d66fe416348851c4dd Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Tue, 18 Jan 2022 17:43:27 +0100 Subject: [PATCH 64/81] Fixed typo in auxiliary indicator fetching by ID. --- Indicators/Indi_BWZT.mqh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 70675404e..5699beba3 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -129,7 +129,7 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { case INDI_AC: return iparams.indi_ac.Ptr(); case INDI_AO: - return iparams.indi_ac.Ptr(); + return iparams.indi_ao.Ptr(); } return NULL; From e17381a9fa4d222cc982d1c5c0c6a8b841a8162f Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 16:35:15 +0000 Subject: [PATCH 65/81] GHA: Compiles based on the file list --- .github/workflows/compile-cpp.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/compile-cpp.yml b/.github/workflows/compile-cpp.yml index 3e075f51c..085b4f3e0 100644 --- a/.github/workflows/compile-cpp.yml +++ b/.github/workflows/compile-cpp.yml @@ -12,12 +12,33 @@ on: jobs: + FileList: + outputs: + filelist: ${{ steps.get-files.outputs.filelist }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set output with list of files + id: get-files + run: | + import glob, json, os + files = glob.glob("**/tests/*.cpp") + print("::set-output name=filelist::{}".format(json.dumps(files))) + shell: python + - name: Display output + run: echo ${{ steps.get-files.outputs.filelist }} + Compile: runs-on: ubuntu-latest + needs: [FileList] + strategy: + matrix: + file: ${{ fromJson(needs.FileList.outputs.filelist) }} steps: - uses: actions/checkout@v2 - name: Install compiler uses: rlalik/setup-cpp-compiler@v1.1 with: compiler: gcc-latest - - run: g++ --version + - name: Compile ${{ matrix.file }} + run: g++ "${{ matrix.file }}" From 0b8be3b1e35ac7fd0350b4413d72635a8a2930a7 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 16:51:11 +0000 Subject: [PATCH 66/81] Adds TradeSignal and TradeSignalManager C++ compilation tests --- Trade/tests/TradeSignal.test.cpp | 32 +++++++++++++++++++++++++ Trade/tests/TradeSignalManager.test.cpp | 32 +++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 Trade/tests/TradeSignal.test.cpp create mode 100644 Trade/tests/TradeSignalManager.test.cpp diff --git a/Trade/tests/TradeSignal.test.cpp b/Trade/tests/TradeSignal.test.cpp new file mode 100644 index 000000000..b230c5123 --- /dev/null +++ b/Trade/tests/TradeSignal.test.cpp @@ -0,0 +1,32 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test C++ compilation of TradeSignal class. + */ + +// Includes. +#include "../../Std.h" +#include "../../Common.define.h" +#include "../../Common.extern.h" +//#include "../../String.extern.h" +#include "../TradeSignal.h" diff --git a/Trade/tests/TradeSignalManager.test.cpp b/Trade/tests/TradeSignalManager.test.cpp new file mode 100644 index 000000000..9017a08f8 --- /dev/null +++ b/Trade/tests/TradeSignalManager.test.cpp @@ -0,0 +1,32 @@ +//+------------------------------------------------------------------+ +//| 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 + * Test C++ compilation of TradeSignalManager class. + */ + +// Includes. +#include "../../Std.h" +#include "../../Common.define.h" +#include "../../Common.extern.h" +#include "../../String.extern.h" +#include "../TradeSignalManager.h" From 6ee889c0de8509bf015718bb383f7c222532f940 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 17:10:19 +0000 Subject: [PATCH 67/81] Fixes EOL characters --- Indicator/IndicatorCandle.h | 8 ++++---- Indicators/Indi_AMA.mqh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 4293af43b..c0ff4637a 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -108,20 +108,20 @@ class IndicatorCandle : public Indicator { int i = 0; while (true) { _curr_candle_time = CalcCandleTimestamp(GetBarTime(i++)); - + if (_curr_candle_time < icdata.GetMin()) { // There is no older entries. break; } - + _candle = icdata.GetByKey(_curr_candle_time); - + if (_candle.IsValid()) { break; } } } - + if (!_candle.IsValid()) { // Giving up. DebugBreak(); diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index ee9e75af9..e72de2fdc 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -180,7 +180,7 @@ class Indi_AMA : public IndicatorTickOrCandleSource { for (int x = prev_calculated; x < rates_total; ++x) { Print("price[", x, "] = ", price[x].Get(), ", O = ", iOpen(Symbol(), PERIOD_CURRENT, Bars(Symbol(), PERIOD_CURRENT) - x - 1)); } - + int i; // Check for rates count. if (rates_total < ExtPeriodAMA + begin) return (0); From 8826b3d27f26274d866fdec0ac7abee020e11b14 Mon Sep 17 00:00:00 2001 From: kenorb Date: Tue, 18 Jan 2022 18:32:58 +0000 Subject: [PATCH 68/81] Trade: Fixes C++ compilation errors --- Common.extern.h | 8 ++++++-- Convert.mqh | 5 +++++ Refs.struct.h | 2 +- SerializerJson.mqh | 1 + String.extern.h | 3 ++- Trade/TradeSignal.struct.h | 3 ++- Trade/TradeSignalManager.struct.h | 2 +- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Common.extern.h b/Common.extern.h index 974a579f9..09343f7d3 100644 --- a/Common.extern.h +++ b/Common.extern.h @@ -23,12 +23,16 @@ // Define external global functions. #ifndef __MQL__ extern void DebugBreak(); -extern void PrintFormat(string format_string, ...); +// Errors. +extern void SetUserError(ushort user_error); // Exceptions. extern int NotImplementedException(); -// Print() templates. +// Print-related functions. +extern void Alert(string arg1); +extern void Alert(string arg1, string arg2); template extern void Print(T arg); template extern void Print(T1 arg1, T2 arg2); +extern void PrintFormat(string format_string, ...); #endif diff --git a/Convert.mqh b/Convert.mqh index 50d81fbd2..a63cef562 100644 --- a/Convert.mqh +++ b/Convert.mqh @@ -24,6 +24,11 @@ #ifndef CONVERT_MQH #define CONVERT_MQH +// Prevents processing this includes file for the second time. +#ifndef __MQL__ +#pragma once +#endif + // Includes. #include "Account.enum.h" #include "Account.extern.h" diff --git a/Refs.struct.h b/Refs.struct.h index dc473df3b..a4c9bc358 100644 --- a/Refs.struct.h +++ b/Refs.struct.h @@ -35,7 +35,7 @@ // Forward class declaration. class Refs; -//class ReferenceCounter; +// class ReferenceCounter; template struct WeakRef; diff --git a/SerializerJson.mqh b/SerializerJson.mqh index 6d7524140..1fce9219b 100644 --- a/SerializerJson.mqh +++ b/SerializerJson.mqh @@ -29,6 +29,7 @@ #include "Object.mqh" #include "Serializer.mqh" #include "SerializerNode.mqh" +#include "String.extern.h" class Log; diff --git a/String.extern.h b/String.extern.h index ee7943b96..428ddedfd 100644 --- a/String.extern.h +++ b/String.extern.h @@ -29,8 +29,9 @@ #ifndef __MQL__ extern datetime StringToTime(const string time_string); extern double StringToDouble(string value); +extern int StringFind(string string_value, string match_substring, int start_pos = 0); extern int StringLen(string string_value); -extern int StringSplit(const string string_value, const ushort separator, string &result[]); +extern int StringSplit(const string string_value, const ushort separator, string result[]); extern long StringToInteger(string value); extern string IntegerToString(long number, int str_len = 0, ushort fill_symbol = ' '); extern string StringFormat(string format, ...); diff --git a/Trade/TradeSignal.struct.h b/Trade/TradeSignal.struct.h index cb9be63fe..746628dfe 100644 --- a/Trade/TradeSignal.struct.h +++ b/Trade/TradeSignal.struct.h @@ -26,6 +26,7 @@ */ // Includes. +#include "../Chart.enum.h" #include "../Serializer.mqh" #include "../SerializerConverter.mqh" #include "../SerializerJson.mqh" @@ -134,7 +135,7 @@ struct TradeSignalEntry { return (T)weight; } SetUserError(ERR_INVALID_PARAMETER); - return (T)WRONG_VALUE; + return (T)NULL; } bool Get(STRUCT_ENUM(TradeSignalEntry, ENUM_TRADE_SIGNAL_FLAG) _prop) { return CheckSignals(_prop); } /* Setters */ diff --git a/Trade/TradeSignalManager.struct.h b/Trade/TradeSignalManager.struct.h index 7e492a21d..3fd69fa17 100644 --- a/Trade/TradeSignalManager.struct.h +++ b/Trade/TradeSignalManager.struct.h @@ -67,7 +67,7 @@ struct TradeSignalManagerParams { return (T)last_check; } SetUserError(ERR_INVALID_PARAMETER); - return (T)WRONG_VALUE; + return (T)NULL; } /* Setters */ From 74eb0367ab71e76aee55d754e5c747efc56125f0 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 19 Jan 2022 12:53:48 +0100 Subject: [PATCH 69/81] IndicatorsTest was set to test only AMA or Pattern indicator. Now it should test all indicators. --- tests/IndicatorsTest.mq5 | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index 357984ae5..22bb10ada 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -111,13 +111,6 @@ void OnTick() { _indi.OnTick(); IndicatorDataEntry _entry(_indi.GetEntry()); - if (_indi.GetType() == INDI_AMA) { - PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); - continue; - } else { - continue; - } - if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { if (_entry.IsValid()) { PrintFormat("%s: bar %d: %s", _indi.GetFullName(), bar_processed, _indi.ToString()); @@ -558,7 +551,7 @@ bool InitIndicators() { } // Push white-listed indicators here. - whitelisted_indis.Push(_indi_test); + // whitelisted_indis.Push(_indi_test); return GetLastError() == ERR_NO_ERROR; } From 1dc8803b6296d9b881764ade8baae74d337f286a Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 19 Jan 2022 16:16:41 +0100 Subject: [PATCH 70/81] Making MQL code to compile in C++. Especially the TradeSignalManager.test.cpp. --- Array.extern.h | 29 +++++++++++++++++----- Array.mqh | 5 ++-- Common.define.h | 1 - Common.extern.h | 23 ++++++++++++------ DateTime.extern.h | 49 ++++++++++++++++++++++++++++++++++++++ DictIteratorBase.mqh | 22 ++++++++--------- DictObject.mqh | 24 +++++++++++++++++-- DictSlotsRef.h | 2 +- Math.extern.h | 7 +++++- MqlTick.h | 2 ++ Refs.struct.h | 2 +- Serializer.mqh | 2 +- SerializerConverter.mqh | 2 +- SerializerJson.mqh | 29 ++++++++++++---------- SerializerNodeIterator.mqh | 27 +++++++++++---------- Std.h | 3 +++ String.extern.h | 3 +-- Trade/TradeSignal.struct.h | 4 ++-- Trade/TradeSignalManager.h | 8 +++---- 19 files changed, 178 insertions(+), 66 deletions(-) diff --git a/Array.extern.h b/Array.extern.h index cef60069d..193e52511 100644 --- a/Array.extern.h +++ b/Array.extern.h @@ -22,10 +22,27 @@ // Define external global functions. #ifndef __MQL__ -extern int ArrayInitialize(); -extern int ArrayResize(void& array[], int new_size, int reserve_size = 0); -extern bool ArrayReverse(); -extern bool ArraySetAsSeries(const void& array[], bool flag); -extern int ArraySize(const void& array[]); -extern bool ArraySort(void& array[]); +#pragma once + +template +extern int ArraySize(const ARRAY_REF(T, _array)); + +template +extern constexpr int ArraySize(const T REF(_array)[size]); + +template +extern int ArrayResize(ARRAY_REF(T, _array), int _new_size, int _reserve_size = 0); + +template +extern bool ArraySetAsSeries(ARRAY_REF(T, _array), bool _flag); + +template +extern int ArrayMaximum(const ARRAY_REF(T, _array), int _start = 0, unsigned int _count = WHOLE_ARRAY); + +template +extern int ArrayMinimum(const ARRAY_REF(T, _array), int _start = 0, unsigned int _count = WHOLE_ARRAY); + +template +extern int ArrayFree(const ARRAY_REF(T, _array)); + #endif diff --git a/Array.mqh b/Array.mqh index c8e549170..1a07d3fc0 100644 --- a/Array.mqh +++ b/Array.mqh @@ -27,10 +27,11 @@ // Includes. #include "Array.extern.h" -#include "Convert.extern.h" #include "Common.extern.h" +#include "Convert.extern.h" #include "Math.extern.h" #include "Std.h" +#include "String.extern.h" // Defines. #ifndef MODE_ASCEND @@ -533,7 +534,7 @@ static int GetLowestArrDoubleValue(double& arr[][], int key) { */ template void ArrayPrint(ARRAY_REF(T, _arr), // Printed array. - int _digits = 0, // Number of decimal places. + int _digits = 0, // Number of decimal places. const string _dlm = NULL, // Separator of the structure field values. long _start = 0, // First printed element index. long _count = WHOLE_ARRAY, // Number of printed elements. diff --git a/Common.define.h b/Common.define.h index c799d9921..b0daac762 100644 --- a/Common.define.h +++ b/Common.define.h @@ -29,7 +29,6 @@ typedef std::string string; typedef unsigned char uchar; typedef unsigned int uint; -typedef unsigned long datetime; typedef unsigned long ulong; typedef unsigned short ushort; #endif diff --git a/Common.extern.h b/Common.extern.h index 09343f7d3..2092a4c16 100644 --- a/Common.extern.h +++ b/Common.extern.h @@ -22,17 +22,26 @@ // Define external global functions. #ifndef __MQL__ +#pragma once +#include "Chart.enum.h" +#include "DateTime.enum.h" + extern void DebugBreak(); // Errors. extern void SetUserError(ushort user_error); // Exceptions. extern int NotImplementedException(); // Print-related functions. -extern void Alert(string arg1); -extern void Alert(string arg1, string arg2); -template -extern void Print(T arg); -template -extern void Print(T1 arg1, T2 arg2); -extern void PrintFormat(string format_string, ...); +template +extern std::string StringFormat(const std::string& format, Args... args); + +template +extern std::string PrintFormat(const std::string& format, Args... args); + +template +extern void Print(Args... args); + +template +extern void Alert(Args... args); + #endif diff --git a/DateTime.extern.h b/DateTime.extern.h index 11e1d0ad8..96257b147 100644 --- a/DateTime.extern.h +++ b/DateTime.extern.h @@ -28,5 +28,54 @@ * Includes external declarations related to date and time. */ #ifndef __MQL__ +#pragma once +// Forward declarations. +struct MqlDateTime; + +/** + * MQL's "datetime" type. + */ +class datetime { + time_t dt; + + public: + datetime(); + datetime(const time_t& _time); + datetime(const long& _time); + datetime(const int& _time); + datetime& operator=(const time_t& _time); + bool operator==(const int& _time) const; + bool operator==(const datetime& _time) const; + bool operator<(const int& _time) const; + bool operator>(const int& _time) const; + bool operator<(const datetime& _time); + bool operator>(const datetime& _time); + operator long() const; +}; + +extern datetime TimeCurrent(); +extern datetime TimeCurrent(MqlDateTime& dt_struct); + +extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, int start_pos, int count, + ARRAY_REF(datetime, time_array)); + +extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, datetime start_time, int count, + ARRAY_REF(datetime, time_array)); + +extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, datetime start_time, datetime stop_time, + ARRAY_REF(datetime, time_array)); + +extern datetime StructToTime(MqlDateTime& dt_struct); +extern bool TimeToStruct(datetime dt, MqlDateTime& dt_struct); +extern datetime TimeGMT(); +extern datetime TimeGMT(MqlDateTime& dt_struct); +extern datetime TimeTradeServer(); +extern datetime TimeTradeServer(MqlDateTime& dt_struct); +extern datetime StringToTime(const string& value); extern string TimeToString(datetime value, int mode = TIME_DATE | TIME_MINUTES); + +template +extern datetime operator"" _D(); + +#define DATETIME_LITERAL(STR) _D " ## STR ## " #endif diff --git a/DictIteratorBase.mqh b/DictIteratorBase.mqh index 16fafb8a8..329fc5cb8 100644 --- a/DictIteratorBase.mqh +++ b/DictIteratorBase.mqh @@ -60,7 +60,7 @@ class DictIteratorBase { */ DictIteratorBase(const DictIteratorBase& right) : _dict(right._dict), - _hash(right._dict ? right._dict.GetHash() : 0), + _hash(right._dict ? right._dict PTR_DEREF GetHash() : 0), _slotIdx(right._slotIdx), _index(right._index) { _invalid_until_incremented = false; @@ -75,24 +75,24 @@ class DictIteratorBase { ++_index; _invalid_until_incremented = false; - DictSlot* slot = _dict.GetSlot(_slotIdx); + DictSlot* slot = _dict PTR_DEREF GetSlot(_slotIdx); // Iterating until we find valid, used slot. - while (slot != NULL && !slot.IsUsed()) { - slot = _dict.GetSlot(++_slotIdx); + while (slot != NULL && !slot PTR_DEREF IsUsed()) { + slot = _dict PTR_DEREF GetSlot(++_slotIdx); } - if (!slot || !slot.IsValid()) { + if (!slot || !slot PTR_DEREF IsValid()) { // Invalidating iterator. _dict = NULL; } } - bool HasKey() { return _dict.GetSlot(_slotIdx).HasKey(); } + bool HasKey() { return _dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF HasKey(); } K Key() { CheckValidity(); - return _dict.GetMode() == DictModeList ? (K)_slotIdx : _dict.GetSlot(_slotIdx).key; + return PTR_ATTRIB(_dict, GetMode()) == DictModeList ? (K)_slotIdx : _dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF key; } string KeyAsString(bool includeQuotes = false) { @@ -106,7 +106,7 @@ class DictIteratorBase { V Value() { CheckValidity(); - return _dict.GetSlot(_slotIdx).value; + return _dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF value; } void CheckValidity() { @@ -121,15 +121,15 @@ class DictIteratorBase { bool IsLast() { if (!IsValid()) return true; - if (_dict.GetMode() == DictModeUnknown || _dict.Size() == 0) { + if (_dict PTR_DEREF GetMode() == DictModeUnknown || _dict.Size() == 0) { return false; } - if (_dict.GetMode() != DictModeList) { + if (_dict PTR_DEREF GetMode() != DictModeList) { Alert("Dict iterator's IsLast() method may be used only when elements are added via Push() method."); } - return _index == _dict.Size() - 1; + return _index == _dict PTR_DEREF Size() - 1; } void ShiftPosition(int shift, bool invalid_until_incremented = false) { diff --git a/DictObject.mqh b/DictObject.mqh index 3585c1972..fbee0bf5c 100644 --- a/DictObject.mqh +++ b/DictObject.mqh @@ -46,7 +46,7 @@ class DictObjectIterator : public DictIteratorBase { */ DictObjectIterator(const DictObjectIterator& right) : DictIteratorBase(right) {} - V* Value() { return &_dict.GetSlot(_slotIdx).value; } + V* Value() { return &(_dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF value); } }; /** @@ -78,6 +78,19 @@ class DictObject : public DictBase { _mode = right._mode; } + DictObjectIterator Begin() { + // Searching for first item index. + for (unsigned int i = 0; i < (unsigned int)ArraySize(_DictSlots_ref.DictSlots); ++i) { + if (_DictSlots_ref.DictSlots[i].IsValid() && _DictSlots_ref.DictSlots[i].IsUsed()) { + DictObjectIterator iter(THIS_REF, i); + return iter; + } + } + // No items found. + DictObjectIterator invalid; + return invalid; + } + void operator=(const DictObject& right) { Clear(); Resize(right.GetSlotCount()); @@ -163,7 +176,9 @@ class DictObject : public DictBase { /** * Checks whether dictionary contains given key => value pair. */ +#ifdef __MQL__ template <> +#endif bool Contains(const K key, const V& value) { unsigned int position; DictSlot* slot = GetSlotByKey(_DictSlots_ref, key, position); @@ -336,11 +351,14 @@ class DictObject : public DictBase { return true; } + public: +#ifdef __MQL__ template <> +#endif SerializerNodeType Serialize(Serializer& s) { if (s.IsWriting()) { for (DictIteratorBase i(Begin()); i.IsValid(); ++i) - s.PassObject(this, GetMode() == DictModeDict ? i.KeyAsString() : "", i.Value()); + s.PassObject(THIS_REF, GetMode() == DictModeDict ? i.KeyAsString() : "", i.Value()); return (GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray; } else { @@ -384,7 +402,9 @@ class DictObject : public DictBase { /** * Initializes object with given number of elements. Could be skipped for non-containers. */ +#ifdef __MQL__ template <> +#endif void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) { V _child; diff --git a/DictSlotsRef.h b/DictSlotsRef.h index 140140c49..ccf9e0b26 100644 --- a/DictSlotsRef.h +++ b/DictSlotsRef.h @@ -38,7 +38,7 @@ class DictSlot; template struct DictSlotsRef { - DictSlot DictSlots[]; + ARRAY(DictSlot, DictSlots); // Incremental index for dict operating in list mode. int _list_index; diff --git a/Math.extern.h b/Math.extern.h index 25b1d1705..8f575b45b 100644 --- a/Math.extern.h +++ b/Math.extern.h @@ -22,5 +22,10 @@ // Define external global functions. #ifndef __MQL__ -extern double MathMax(double value1, double value2); +extern double MathAbs(double value); +extern double fabs(double value); +template +extern T MathMax(T value1, T value2); +template +extern T MathMin(T value1, T value2); #endif diff --git a/MqlTick.h b/MqlTick.h index 241e807b5..e6d6466dd 100644 --- a/MqlTick.h +++ b/MqlTick.h @@ -29,6 +29,8 @@ #pragma once #endif +#include "DateTime.extern.h" + #ifndef __MQL__ /** * Structure for storing the latest prices of the symbol. diff --git a/Refs.struct.h b/Refs.struct.h index a4c9bc358..e06998fa9 100644 --- a/Refs.struct.h +++ b/Refs.struct.h @@ -35,7 +35,7 @@ // Forward class declaration. class Refs; -// class ReferenceCounter; +class ReferenceCounter; template struct WeakRef; diff --git a/Serializer.mqh b/Serializer.mqh index 9f08044d0..006839a67 100644 --- a/Serializer.mqh +++ b/Serializer.mqh @@ -72,7 +72,7 @@ class Serializer { template SerializerIterator Begin() { - SerializerIterator iter(&this, _node); + SerializerIterator iter(THIS_PTR, _node); return iter; } diff --git a/SerializerConverter.mqh b/SerializerConverter.mqh index ef6eb2328..f22b77f03 100644 --- a/SerializerConverter.mqh +++ b/SerializerConverter.mqh @@ -96,7 +96,7 @@ class SerializerConverter { template string ToString(unsigned int stringify_flags = 0, void* stringify_aux_arg = NULL) { - string result = ((R*)NULL).Stringify(root_node, stringify_flags, stringify_aux_arg); + string result = ((R*)NULL)PTR_DEREF Stringify(root_node, stringify_flags, stringify_aux_arg); if ((_serializer_flags & SERIALIZER_FLAG_REUSE_OBJECT) == 0) { Clean(); } diff --git a/SerializerJson.mqh b/SerializerJson.mqh index 1fce9219b..8465f82c2 100644 --- a/SerializerJson.mqh +++ b/SerializerJson.mqh @@ -65,10 +65,12 @@ class SerializerJson { repr += ident; - if (PTR_ATTRIB(_node, GetKeyParam()) != NULL && PTR_ATTRIB(PTR_ATTRIB(_node, GetKeyParam()), AsString(false, false)) != "") + if (PTR_ATTRIB(_node, GetKeyParam()) != NULL && + PTR_ATTRIB(PTR_ATTRIB(_node, GetKeyParam()), AsString(false, false)) != "") repr += PTR_ATTRIB(PTR_ATTRIB(_node, GetKeyParam()), AsString(false, true)) + ":" + (trimWhitespaces ? "" : " "); - if (PTR_ATTRIB(_node, GetValueParam()) != NULL) repr += PTR_ATTRIB(PTR_ATTRIB(_node, GetValueParam()), AsString(false, true)); + if (PTR_ATTRIB(_node, GetValueParam()) != NULL) + repr += PTR_ATTRIB(PTR_ATTRIB(_node, GetValueParam()), AsString(false, true)); switch (PTR_ATTRIB(_node, GetType())) { case SerializerNodeObject: @@ -178,9 +180,10 @@ class SerializerJson { expectingKey = false; expectingSemicolon = true; } else if (expectingValue) { - PTR_ATTRIB(current, AddChild(new SerializerNode( - PTR_ATTRIB(current, GetType()) == SerializerNodeObject ? SerializerNodeObjectProperty : SerializerNodeArrayItem, - current, key, SerializerNodeParam::FromString(extracted)))); + PTR_ATTRIB(current, AddChild(new SerializerNode(PTR_ATTRIB(current, GetType()) == SerializerNodeObject + ? SerializerNodeObjectProperty + : SerializerNodeArrayItem, + current, key, SerializerNodeParam::FromString(extracted)))); #ifdef __debug__ Print("SerializerJson: Value \"" + extracted + "\" for key " + @@ -280,9 +283,10 @@ class SerializerJson { (key != NULL ? ("\"" + key.ToString() + "\"") : "")); #endif - PTR_ATTRIB(current, AddChild(new SerializerNode( - PTR_ATTRIB(current, GetType()) == SerializerNodeObject ? SerializerNodeObjectProperty : SerializerNodeArrayItem, current, - key, value))); + PTR_ATTRIB(current, AddChild(new SerializerNode(PTR_ATTRIB(current, GetType()) == SerializerNodeObject + ? SerializerNodeObjectProperty + : SerializerNodeArrayItem, + current, key, value))); expectingValue = false; // Skipping value. @@ -303,9 +307,10 @@ class SerializerJson { // Skipping value. i += ch == 't' ? 3 : 4; - PTR_ATTRIB(current, AddChild(new SerializerNode( - PTR_ATTRIB(current, GetType()) == SerializerNodeObject ? SerializerNodeObjectProperty : SerializerNodeArrayItem, current, - key, value))); + PTR_ATTRIB(current, AddChild(new SerializerNode(PTR_ATTRIB(current, GetType()) == SerializerNodeObject + ? SerializerNodeObjectProperty + : SerializerNodeArrayItem, + current, key, value))); expectingValue = false; // We don't want to delete it twice. @@ -342,7 +347,7 @@ class SerializerJson { string str; for (unsigned int i = index; i < (unsigned int)StringLen(data); ++i) { -#ifdef __MQL5__ +#ifndef __MQL4__ unsigned short ch = StringGetCharacter(data, i); #else unsigned short ch = StringGetChar(data, i); diff --git a/SerializerNodeIterator.mqh b/SerializerNodeIterator.mqh index 3a1f0f00f..ad3b29c9a 100644 --- a/SerializerNodeIterator.mqh +++ b/SerializerNodeIterator.mqh @@ -54,8 +54,7 @@ class SerializerNodeIterator { /** * Returns current node or NULL. */ - SerializerNode* Node() { return !IsValid() ? NULL : PTR_ATTRIB(_collection, GetChild(_index)); - } + SerializerNode* Node() { return !IsValid() ? NULL : PTR_ATTRIB(_collection, GetChild(_index)); } /** * Returns current node index. @@ -70,25 +69,23 @@ class SerializerNodeIterator { /** * Checks whether iterator is still valid. */ - bool IsValid() { return _index < PTR_ATTRIB(_collection, NumChildren()); - } + bool IsValid() { return _index < PTR_ATTRIB(_collection, NumChildren()); } /** * Returns current's child key or empty string. */ - const string Key() { return !IsValid() ? "" : PTR_ATTRIB(PTR_ATTRIB(_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 : PTR_ATTRIB(PTR_ATTRIB(_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 : PTR_ATTRIB(PTR_ATTRIB(_collection, GetChild(_index)), IsContainer()); + bool IsContainer() { + return !IsValid() ? false : PTR_ATTRIB(PTR_ATTRIB(_collection, GetChild(_index)), IsContainer()); } }; @@ -114,17 +111,21 @@ class SerializerIterator : public SerializerNodeIterator { /** * Returns next value or value by given key. */ +#ifdef __MQL__ template <> +#endif X Value(string key = "") { X value; - _serializer.Pass(_serializer, key, value); + _serializer PTR_DEREF Pass(PTR_TO_REF(_serializer), key, value); return value; } /** * Returns next object or object by given key. */ +#ifdef __MQL__ template <> +#endif X Object(string key = "") { return Struct(key); } @@ -132,14 +133,16 @@ class SerializerIterator : public SerializerNodeIterator { /** * Returns next structure or structure by given key. */ +#ifdef __MQL__ template <> +#endif X Struct(string key = "") { X value; - _serializer.PassStruct(_serializer, key, value); + _serializer PTR_DEREF PassStruct(PTR_TO_REF(_serializer), key, value); return value; } - SerializerNodeType ParentNodeType() { return _collection.GetType(); } + SerializerNodeType ParentNodeType() { return _collection PTR_DEREF GetType(); } }; #endif diff --git a/Std.h b/Std.h index 642b44237..2a915fb92 100644 --- a/Std.h +++ b/Std.h @@ -43,6 +43,7 @@ #ifdef __MQL__ #define THIS_PTR (&this) #define THIS_REF this +#define PTR_DEREF . #define PTR_ATTRIB(O, A) O.A #define PTR_ATTRIB2(O, A, B) O.A.B #define PTR_TO_REF(PTR) PTR @@ -50,6 +51,7 @@ #else #define THIS_PTR (this) #define THIS_REF (*this) +#define PTR_DEREF -> #define PTR_ATTRIB(O, A) O->A #define PTR_ATTRIB2(O, A, B) O->A->B #define PTR_TO_REF(PTR) (*PTR) @@ -64,6 +66,7 @@ #endif // Arrays and references to arrays. +#define _COMMA , #ifdef __MQL__ #define ARRAY_DECLARATION_BRACKETS [] #else diff --git a/String.extern.h b/String.extern.h index 428ddedfd..47a6ff3e3 100644 --- a/String.extern.h +++ b/String.extern.h @@ -27,11 +27,10 @@ // Define external global functions. #ifndef __MQL__ -extern datetime StringToTime(const string time_string); extern double StringToDouble(string value); extern int StringFind(string string_value, string match_substring, int start_pos = 0); extern int StringLen(string string_value); -extern int StringSplit(const string string_value, const ushort separator, string result[]); +extern int StringSplit(const string& string_value, const unsigned short separator, ARRAY_REF(string, result)); extern long StringToInteger(string value); extern string IntegerToString(long number, int str_len = 0, ushort fill_symbol = ' '); extern string StringFormat(string format, ...); diff --git a/Trade/TradeSignal.struct.h b/Trade/TradeSignal.struct.h index 746628dfe..48661c5a5 100644 --- a/Trade/TradeSignal.struct.h +++ b/Trade/TradeSignal.struct.h @@ -116,7 +116,7 @@ struct TradeSignalEntry { TradeSignalEntry(unsigned int _signals = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, long _magic_id = 0, float _strength = 0.0f, float _weight = 0.0f, long _time = 0) : magic_id(_magic_id), signals(_signals), strength(_strength), tf(_tf), timestamp(_time), weight(_weight) {} - TradeSignalEntry(const TradeSignalEntry &_entry) { this = _entry; } + TradeSignalEntry(const TradeSignalEntry &_entry) { THIS_REF = _entry; } /* Getters */ template T Get(STRUCT_ENUM(TradeSignalEntry, ENUM_TRADE_SIGNAL_PROP) _prop) { @@ -190,7 +190,7 @@ struct TradeSignalEntry { int _size = sizeof(int) * 8; for (int i = 0; i < _size; i++) { int _value = CheckSignals(1 << i) ? 1 : 0; - _s.Pass(THIS_REF, (string)(i + 1), _value, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); + _s.Pass(THIS_REF, IntegerToString(i + 1), _value, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); } return SerializerNodeObject; } diff --git a/Trade/TradeSignalManager.h b/Trade/TradeSignalManager.h index 4871e145c..34d98165b 100644 --- a/Trade/TradeSignalManager.h +++ b/Trade/TradeSignalManager.h @@ -124,14 +124,14 @@ class TradeSignalManager : Dynamic { void Refresh() { for (DictObjectIterator iter = GetIterSignalsActive(); iter.IsValid(); ++iter) { TradeSignal *_signal = iter.Value(); - if (_signal.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_PROCESSED))) { + if (_signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_PROCESSED))) { signals_active.Unset(iter); - signals_processed.Push(_signal); + signals_processed.Push(PTR_TO_REF(_signal)); continue; } - if (_signal.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_EXPIRED))) { + if (_signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_EXPIRED))) { signals_active.Unset(iter); - signals_expired.Push(_signal); + signals_expired.Push(PTR_TO_REF(_signal)); continue; } } From 1c8a2edea1760f1178c0d08f8bee2026172160c0 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Thu, 20 Jan 2022 19:19:58 +0100 Subject: [PATCH 71/81] State in the art of MQL/C++ compatibility. --- Array.extern.h | 9 ++ Condition.mqh | 6 +- Convert.mqh | 3 +- DateTime.extern.h | 2 - Dict.enum.h | 21 ++++ DictBase.mqh | 25 +--- DictObject.mqh | 106 ++++++++-------- MQL4.mqh | 90 +++++++------- Mail.mqh | 30 +++-- Math.extern.h | 22 +++- Matrix.mqh | 5 +- Orders.mqh | 14 +-- Refs.mqh | 50 +------- Refs.rc.h | 82 +++++++++++++ Refs.struct.h | 19 +-- Serializer.mqh | 36 +++--- SerializerConverter.mqh | 2 + SerializerDict.mqh | 10 +- SerializerJson.mqh | 4 +- SerializerNodeIterator.mqh | 1 + Std.h | 6 + String.extern.h | 3 + SymbolInfo.static.h | 5 +- Ticker.mqh | 6 +- Timer.mqh | 243 +++++++++++++++++-------------------- Trade/TradeSignal.struct.h | 1 - 26 files changed, 429 insertions(+), 372 deletions(-) create mode 100644 Refs.rc.h diff --git a/Array.extern.h b/Array.extern.h index 193e52511..b09748d67 100644 --- a/Array.extern.h +++ b/Array.extern.h @@ -45,4 +45,13 @@ extern int ArrayMinimum(const ARRAY_REF(T, _array), int _start = 0, unsigned int template extern int ArrayFree(const ARRAY_REF(T, _array)); +template +extern int ArrayReverse(const ARRAY_REF(T, _array)); + +template +extern int ArrayInitialize(ARRAY_REF(T, array), char value); + +template +extern int ArraySort(ARRAY_REF(T, array)); + #endif diff --git a/Condition.mqh b/Condition.mqh index 915cbcd4e..2955f7ffa 100644 --- a/Condition.mqh +++ b/Condition.mqh @@ -109,13 +109,13 @@ class Condition { if (_entry.IsActive()) { switch (_entry.next_statement) { case COND_AND: - _curr_result = _prev_result && this.Test(_entry); + _curr_result = _prev_result && this PTR_DEREF Test(_entry); break; case COND_OR: - _curr_result = _prev_result || this.Test(_entry); + _curr_result = _prev_result || this PTR_DEREF Test(_entry); break; case COND_SEQ: - _curr_result = this.Test(_entry); + _curr_result = this PTR_DEREF Test(_entry); if (!_curr_result) { // Do not check further conditions when the current condition is false. return false; diff --git a/Convert.mqh b/Convert.mqh index a63cef562..c6d52ab38 100644 --- a/Convert.mqh +++ b/Convert.mqh @@ -34,6 +34,7 @@ #include "Account.extern.h" #include "Array.mqh" #include "Convert.extern.h" +#include "Math.extern.h" #include "Order.enum.h" #include "SymbolInfo.enum.h" #include "SymbolInfo.extern.h" @@ -101,7 +102,7 @@ class Convert { /** * Points per pip given digits after decimal point of a symbol price. */ - static uint PointsPerPip(uint digits) { return (uint)pow(10, digits - (digits < 4 ? 2 : 4)); } + static uint PointsPerPip(uint digits) { return (uint)pow((unsigned int)10, digits - (digits < 4 ? 2 : 4)); } /** * Returns number of points per pip. diff --git a/DateTime.extern.h b/DateTime.extern.h index 96257b147..87d156d81 100644 --- a/DateTime.extern.h +++ b/DateTime.extern.h @@ -40,10 +40,8 @@ class datetime { public: datetime(); - datetime(const time_t& _time); datetime(const long& _time); datetime(const int& _time); - datetime& operator=(const time_t& _time); bool operator==(const int& _time) const; bool operator==(const datetime& _time) const; bool operator<(const int& _time) const; diff --git a/Dict.enum.h b/Dict.enum.h index 33887918c..080a50271 100644 --- a/Dict.enum.h +++ b/Dict.enum.h @@ -32,3 +32,24 @@ #define DICT_GROW_UP_PERCENT_DEFAULT 25 #define DICT_PERFORMANCE_PROBLEM_AVG_CONFLICTS 10 + +/** + * Whether Dict operates in yet uknown mode, as dict or as list. + */ +enum DictMode { DictModeUnknown, DictModeDict, DictModeList }; + +/** + * Reason of call to overflow listener. + */ +enum ENUM_DICT_OVERFLOW_REASON { + DICT_OVERFLOW_REASON_FULL, + DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS, +}; + +/** + * Dictionary flags. + */ +enum ENUM_DICT_FLAG { + DICT_FLAG_NONE = 0, + DICT_FLAG_FILL_HOLES_UNSORTED = 1, +}; diff --git a/DictBase.mqh b/DictBase.mqh index 534f91e8a..5c3ab43e5 100644 --- a/DictBase.mqh +++ b/DictBase.mqh @@ -31,27 +31,6 @@ #include "DictSlot.mqh" #include "Serializer.mqh" -/** - * Whether Dict operates in yet uknown mode, as dict or as list. - */ -enum DictMode { DictModeUnknown, DictModeDict, DictModeList }; - -/** - * Reason of call to overflow listener. - */ -enum ENUM_DICT_OVERFLOW_REASON { - DICT_OVERFLOW_REASON_FULL, - DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS, -}; - -/** - * Dictionary flags. - */ -enum ENUM_DICT_FLAG { - DICT_FLAG_NONE = 0, - DICT_FLAG_FILL_HOLES_UNSORTED = 1, -}; - /** * Dictionary overflow listener. arguments are: * - ENUM_DICT_OVERFLOW_REASON overflow_reason @@ -361,10 +340,10 @@ class DictBase { * Specialization of hashing function. */ unsigned int Hash(const string& x) { - unsigned char c[]; + ARRAY(unsigned char, c); unsigned int h = 0; - if (x != NULL) { + if (!IsNull(x)) { h = 5381; int n = StringToCharArray(x, c); for (int i = 0; i < n; i++) { diff --git a/DictObject.mqh b/DictObject.mqh index fbee0bf5c..fd1e75b9a 100644 --- a/DictObject.mqh +++ b/DictObject.mqh @@ -39,14 +39,14 @@ class DictObjectIterator : public DictIteratorBase { /** * Constructor. */ - DictObjectIterator(DictBase& dict, unsigned int slotIdx) : DictIteratorBase(dict, slotIdx) {} + DictObjectIterator(DictBase& dict, unsigned int slotIdx) : DictIteratorBase(dict, slotIdx) {} /** * Copy constructor. */ - DictObjectIterator(const DictObjectIterator& right) : DictIteratorBase(right) {} + DictObjectIterator(const DictObjectIterator& right) : DictIteratorBase(right) {} - V* Value() { return &(_dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF value); } + V* Value() { return &(this PTR_DEREF _dict PTR_DEREF GetSlot(this PTR_DEREF _slotIdx) PTR_DEREF value); } }; /** @@ -71,17 +71,17 @@ class DictObject : public DictBase { Clear(); Resize(right.GetSlotCount()); for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) { - _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; + this PTR_DEREF _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; } - _DictSlots_ref._num_used = right._DictSlots_ref._num_used; - _current_id = right._current_id; - _mode = right._mode; + this PTR_DEREF _DictSlots_ref._num_used = right._DictSlots_ref._num_used; + this PTR_DEREF _current_id = right._current_id; + this PTR_DEREF _mode = right._mode; } DictObjectIterator Begin() { // Searching for first item index. - for (unsigned int i = 0; i < (unsigned int)ArraySize(_DictSlots_ref.DictSlots); ++i) { - if (_DictSlots_ref.DictSlots[i].IsValid() && _DictSlots_ref.DictSlots[i].IsUsed()) { + for (unsigned int i = 0; i < (unsigned int)ArraySize(this PTR_DEREF _DictSlots_ref.DictSlots); ++i) { + if (this PTR_DEREF _DictSlots_ref.DictSlots[i].IsValid() && this PTR_DEREF _DictSlots_ref.DictSlots[i].IsUsed()) { DictObjectIterator iter(THIS_REF, i); return iter; } @@ -95,26 +95,26 @@ class DictObject : public DictBase { Clear(); Resize(right.GetSlotCount()); for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) { - _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; + this PTR_DEREF _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; } - _DictSlots_ref._num_used = right._DictSlots_ref._num_used; - _current_id = right._current_id; - _mode = right._mode; + this PTR_DEREF _DictSlots_ref._num_used = right._DictSlots_ref._num_used; + this PTR_DEREF _current_id = right._current_id; + this PTR_DEREF _mode = right._mode; } void Clear() { - for (unsigned int i = 0; i < (unsigned int)ArraySize(_DictSlots_ref.DictSlots); ++i) { - _DictSlots_ref.DictSlots[i].SetFlags(0); + for (unsigned int i = 0; i < (unsigned int)ArraySize(this PTR_DEREF _DictSlots_ref.DictSlots); ++i) { + this PTR_DEREF _DictSlots_ref.DictSlots[i].SetFlags(0); } - _DictSlots_ref._num_used = 0; + this PTR_DEREF _DictSlots_ref._num_used = 0; } /** * Inserts value using hashless key. */ bool Push(V& value) { - if (!InsertInto(_DictSlots_ref, value)) return false; + if (!InsertInto(this PTR_DEREF _DictSlots_ref, value)) return false; return true; } @@ -127,7 +127,7 @@ class DictObject : public DictBase { * Inserts or replaces value for a given key. */ bool Set(K key, V& value) { - if (!InsertInto(_DictSlots_ref, key, value, true)) return false; + if (!InsertInto(this PTR_DEREF _DictSlots_ref, key, value, true)) return false; return true; } @@ -136,10 +136,10 @@ class DictObject : public DictBase { unsigned int position; - if (_mode == DictModeList) - slot = GetSlot((unsigned int)key); + if (this PTR_DEREF _mode == DictModeList) + slot = this PTR_DEREF GetSlot((unsigned int)key); else - slot = GetSlotByKey(_DictSlots_ref, key, position); + slot = GetSlotByKey(this PTR_DEREF _DictSlots_ref, key, position); if (slot == NULL || !slot.IsUsed()) return NULL; @@ -151,7 +151,7 @@ class DictObject : public DictBase { */ V* GetByKey(const K _key) { unsigned int position; - DictSlot* slot = GetSlotByKey(_DictSlots_ref, _key, position); + DictSlot* slot = GetSlotByKey(this PTR_DEREF _DictSlots_ref, _key, position); if (!slot) return NULL; @@ -162,7 +162,7 @@ class DictObject : public DictBase { * Returns value for a given position. */ V* GetByPos(unsigned int _position) { - DictSlot* slot = GetSlotByPos(_DictSlots_ref, _position); + DictSlot* slot = this PTR_DEREF GetSlotByPos(this PTR_DEREF _DictSlots_ref, _position); if (!slot) { Alert("Invalid DictStruct position \"", _position, "\" (called by GetByPos()). Returning empty structure."); @@ -181,7 +181,7 @@ class DictObject : public DictBase { #endif bool Contains(const K key, const V& value) { unsigned int position; - DictSlot* slot = GetSlotByKey(_DictSlots_ref, key, position); + DictSlot* slot = GetSlotByKey(this PTR_DEREF _DictSlots_ref, key, position); if (!slot) return false; @@ -200,24 +200,24 @@ class DictObject : public DictBase { } } - if (_mode == DictModeUnknown) - _mode = DictModeDict; - else if (_mode != DictModeDict) { + if (this PTR_DEREF _mode == DictModeUnknown) + this PTR_DEREF _mode = DictModeDict; + else if (this PTR_DEREF _mode != DictModeDict) { Alert("Warning: Dict already operates as a list, not a dictionary!"); DebugBreak(); return false; } unsigned int position; - DictSlot* keySlot = GetSlotByKey(dictSlotsRef, key, position); + DictSlot* keySlot = this PTR_DEREF GetSlotByKey(dictSlotsRef, key, position); if (keySlot == NULL && dictSlotsRef._num_used == ArraySize(dictSlotsRef.DictSlots)) { // No DictSlotsRef.DictSlots available. - if (overflow_listener != NULL) { - if (!overflow_listener(DICT_OVERFLOW_REASON_FULL, dictSlotsRef._num_used, 0)) { + if (this PTR_DEREF overflow_listener != NULL) { + if (!this PTR_DEREF overflow_listener(DICT_OVERFLOW_REASON_FULL, dictSlotsRef._num_used, 0)) { // Overwriting slot pointed exactly by key's position in the hash table (we don't check for possible // conflicts). - keySlot = &dictSlotsRef.DictSlots[Hash(key) % ArraySize(dictSlotsRef.DictSlots)]; + keySlot = &dictSlotsRef.DictSlots[this PTR_DEREF Hash(key) % ArraySize(dictSlotsRef.DictSlots)]; } } @@ -228,7 +228,7 @@ class DictObject : public DictBase { } if (keySlot == NULL) { - position = Hash(key) % ArraySize(dictSlotsRef.DictSlots); + position = this PTR_DEREF Hash(key) % ArraySize(dictSlotsRef.DictSlots); unsigned int _starting_position = position; int _num_conflicts = 0; @@ -237,9 +237,11 @@ class DictObject : public DictBase { // Searching for empty DictSlot or used one with the matching key. It skips used, hashless DictSlots. while (dictSlotsRef.DictSlots[position].IsUsed() && (!dictSlotsRef.DictSlots[position].HasKey() || dictSlotsRef.DictSlots[position].key != key)) { - if (overflow_listener_max_conflicts != 0 && ++_num_conflicts == overflow_listener_max_conflicts) { - if (overflow_listener != NULL) { - if (!overflow_listener(DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS, dictSlotsRef._num_used, _num_conflicts)) { + if (this PTR_DEREF overflow_listener_max_conflicts != 0 && + ++_num_conflicts == this PTR_DEREF overflow_listener_max_conflicts) { + if (this PTR_DEREF overflow_listener != NULL) { + if (!this PTR_DEREF overflow_listener(DICT_OVERFLOW_REASON_TOO_MANY_CONFLICTS, dictSlotsRef._num_used, + _num_conflicts)) { // Overflow listener returned false so we won't search for further empty slot. _overwrite_slot = true; break; @@ -277,9 +279,9 @@ class DictObject : public DictBase { * Inserts hashless value into given array of DictSlots. */ bool InsertInto(DictSlotsRef& dictSlotsRef, V& value) { - if (_mode == DictModeUnknown) - _mode = DictModeList; - else if (_mode != DictModeList) { + if (this PTR_DEREF _mode == DictModeUnknown) + this PTR_DEREF _mode = DictModeList; + else if (this PTR_DEREF _mode != DictModeList) { Alert("Warning: Dict already operates as a dictionary, not a list!"); DebugBreak(); return false; @@ -290,7 +292,8 @@ class DictObject : public DictBase { if (!GrowUp()) return false; } - unsigned int position = Hash((unsigned int)dictSlotsRef._list_index) % ArraySize(dictSlotsRef.DictSlots); + unsigned int position = + this PTR_DEREF Hash((unsigned int)dictSlotsRef._list_index) % ArraySize(dictSlotsRef.DictSlots); // Searching for empty DictSlot. while (dictSlotsRef.DictSlots[position].IsUsed()) { @@ -310,14 +313,16 @@ class DictObject : public DictBase { * Expands array of DictSlots by given percentage value. */ bool GrowUp(int percent = DICT_GROW_UP_PERCENT_DEFAULT) { - return Resize(MathMax(10, (int)((float)ArraySize(_DictSlots_ref.DictSlots) * ((float)(percent + 100) / 100.0f)))); + return Resize(MathMax( + 10, (int)((float)ArraySize(this PTR_DEREF _DictSlots_ref.DictSlots) * ((float)(percent + 100) / 100.0f)))); } /** * Shrinks or expands array of DictSlots. */ bool Resize(int new_size) { - if (new_size <= MathMin(_DictSlots_ref._num_used, ArraySize(_DictSlots_ref.DictSlots))) { + if (new_size <= + MathMin(this PTR_DEREF _DictSlots_ref._num_used, ArraySize(this PTR_DEREF _DictSlots_ref.DictSlots))) { // We already use minimum number of slots possible. return true; } @@ -333,20 +338,21 @@ class DictObject : public DictBase { } // Copies entire array of DictSlots into new array of DictSlots. Hashes will be rehashed. - for (i = 0; i < ArraySize(_DictSlots_ref.DictSlots); ++i) { - if (!_DictSlots_ref.DictSlots[i].IsUsed()) continue; + for (i = 0; i < ArraySize(this PTR_DEREF _DictSlots_ref.DictSlots); ++i) { + if (!this PTR_DEREF _DictSlots_ref.DictSlots[i].IsUsed()) continue; - if (_DictSlots_ref.DictSlots[i].HasKey()) { - if (!InsertInto(new_DictSlots, _DictSlots_ref.DictSlots[i].key, _DictSlots_ref.DictSlots[i].value, false)) + if (this PTR_DEREF _DictSlots_ref.DictSlots[i].HasKey()) { + if (!InsertInto(new_DictSlots, this PTR_DEREF _DictSlots_ref.DictSlots[i].key, + this PTR_DEREF _DictSlots_ref.DictSlots[i].value, false)) return false; } else { - if (!InsertInto(new_DictSlots, _DictSlots_ref.DictSlots[i].value)) return false; + if (!InsertInto(new_DictSlots, this PTR_DEREF _DictSlots_ref.DictSlots[i].value)) return false; } } // Freeing old DictSlots array. - ArrayFree(_DictSlots_ref.DictSlots); + ArrayFree(this PTR_DEREF _DictSlots_ref.DictSlots); - _DictSlots_ref = new_DictSlots; + this PTR_DEREF _DictSlots_ref = new_DictSlots; return true; } @@ -358,9 +364,9 @@ class DictObject : public DictBase { SerializerNodeType Serialize(Serializer& s) { if (s.IsWriting()) { for (DictIteratorBase i(Begin()); i.IsValid(); ++i) - s.PassObject(THIS_REF, GetMode() == DictModeDict ? i.KeyAsString() : "", i.Value()); + s.PassObject(THIS_REF, this PTR_DEREF GetMode() == DictModeDict ? i.KeyAsString() : "", i.Value()); - return (GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray; + return (this PTR_DEREF GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray; } else { if (s.IsArray()) { unsigned int num_items = s.NumArrayItems(); diff --git a/MQL4.mqh b/MQL4.mqh index 42901ff73..b3e5c850c 100644 --- a/MQL4.mqh +++ b/MQL4.mqh @@ -155,29 +155,30 @@ class MT4HISTORY { const datetime LastTimeCurrent = ::TimeCurrent(); - if ((!MT4HISTORY::IsTester) && (LastTimeCurrent >= this.LastInitTime + DAY)) { - this.LastTime = 0; + if ((!MT4HISTORY::IsTester) && (LastTimeCurrent >= this PTR_DEREF LastInitTime + DAY)) { + this PTR_DEREF LastTime = 0; - this.LastTotalOrders = 0; - this.LastTotalDeals = 0; + this PTR_DEREF LastTotalOrders = 0; + this PTR_DEREF LastTotalDeals = 0; - this.Amount = 0; + this PTR_DEREF Amount = 0; - ::ArrayResize(this.Tickets, this.Amount, RESERVE_SIZE); + ::ArrayResize(this PTR_DEREF Tickets, this PTR_DEREF Amount, RESERVE_SIZE); - this.LastInitTime = LastTimeCurrent; + this PTR_DEREF LastInitTime = LastTimeCurrent; } - if (::HistorySelect(this.LastTime, ::MathMax(LastTimeCurrent, this.LastTime) + DAY)) // Daily stock. + if (::HistorySelect(this PTR_DEREF LastTime, + ::MathMax(LastTimeCurrent, this PTR_DEREF LastTime) + DAY)) // Daily stock. { const int TotalOrders = ::HistoryOrdersTotal(); const int TotalDeals = ::HistoryDealsTotal(); - Res = ((TotalOrders != this.LastTotalOrders) || (TotalDeals != this.LastTotalDeals)); + Res = ((TotalOrders != this PTR_DEREF LastTotalOrders) || (TotalDeals != this PTR_DEREF LastTotalDeals)); if (Res) { - int iOrder = MT4HISTORY::GetNextPosMT4Order(this.LastTotalOrders); - int iDeal = MT4HISTORY::GetNextPosMT4Deal(this.LastTotalDeals); + int iOrder = MT4HISTORY::GetNextPosMT4Order(this PTR_DEREF LastTotalOrders); + int iDeal = MT4HISTORY::GetNextPosMT4Deal(this PTR_DEREF LastTotalDeals); long TimeOrder = (iOrder < TotalOrders) ? ::HistoryOrderGetInteger(::HistoryOrderGetTicket(iOrder), ORDER_TIME_DONE /*_MSC*/) @@ -188,9 +189,9 @@ class MT4HISTORY { while ((iDeal < TotalDeals) || (iOrder < TotalOrders)) if (TimeOrder < TimeDeal) { - this.Amount = ::ArrayResize(this.Tickets, this.Amount + 1, RESERVE_SIZE); + this PTR_DEREF Amount = ::ArrayResize(this PTR_DEREF Tickets, this PTR_DEREF Amount + 1, RESERVE_SIZE); - this.Tickets[this.Amount - 1] = -(long)::HistoryOrderGetTicket(iOrder); + this PTR_DEREF Tickets[this PTR_DEREF Amount - 1] = -(long)::HistoryOrderGetTicket(iOrder); iOrder = MT4HISTORY::GetNextPosMT4Order(iOrder + 1); @@ -198,9 +199,9 @@ class MT4HISTORY { ? ::HistoryOrderGetInteger(::HistoryOrderGetTicket(iOrder), ORDER_TIME_DONE /*_MSC*/) : LONG_MAX; // ORDER_TIME_DONE_MSC returns zero in the tester (build 1470). } else { - this.Amount = ::ArrayResize(this.Tickets, this.Amount + 1, RESERVE_SIZE); + this PTR_DEREF Amount = ::ArrayResize(this PTR_DEREF Tickets, this PTR_DEREF Amount + 1, RESERVE_SIZE); - this.Tickets[this.Amount - 1] = (long)::HistoryDealGetTicket(iDeal); + this PTR_DEREF Tickets[this PTR_DEREF Amount - 1] = (long)::HistoryDealGetTicket(iDeal); iDeal = MT4HISTORY::GetNextPosMT4Deal(iDeal + 1); @@ -216,19 +217,19 @@ class MT4HISTORY { const long MaxTime = ::MathMax(TimeOrder, TimeDeal); - this.LastTotalOrders = 0; - this.LastTotalDeals = 0; + this PTR_DEREF LastTotalOrders = 0; + this PTR_DEREF LastTotalDeals = 0; if (LastTimeCurrent - HISTORY_PAUSE > MaxTime) - this.LastTime = LastTimeCurrent - HISTORY_PAUSE; + this PTR_DEREF LastTime = LastTimeCurrent - HISTORY_PAUSE; else { - this.LastTime = (datetime)MaxTime; + this PTR_DEREF LastTime = (datetime)MaxTime; if (TimeOrder == MaxTime) for (int i = TotalOrders - 1; i >= 0; i--) { if (TimeOrder > ::HistoryOrderGetInteger(::HistoryOrderGetTicket(i), ORDER_TIME_DONE /*_MSC*/)) break; - this.LastTotalOrders++; + this PTR_DEREF LastTotalOrders++; } if (TimeDeal == MaxTime) @@ -236,14 +237,14 @@ class MT4HISTORY { if (TimeDeal != ::HistoryDealGetInteger(::HistoryDealGetTicket(TotalDeals - 1), DEAL_TIME /*_MSC*/)) break; - this.LastTotalDeals++; + this PTR_DEREF LastTotalDeals++; } } - } else if (LastTimeCurrent - HISTORY_PAUSE > this.LastTime) { - this.LastTime = LastTimeCurrent - HISTORY_PAUSE; + } else if (LastTimeCurrent - HISTORY_PAUSE > this PTR_DEREF LastTime) { + this PTR_DEREF LastTime = LastTimeCurrent - HISTORY_PAUSE; - this.LastTotalOrders = 0; - this.LastTotalDeals = 0; + this PTR_DEREF LastTotalOrders = 0; + this PTR_DEREF LastTotalDeals = 0; } } @@ -264,26 +265,26 @@ class MT4HISTORY { } MT4HISTORY(void) : Amount(0), LastTime(0), LastTotalDeals(0), LastTotalOrders(0), LastInitTime(0) { - ::ArrayResize(this.Tickets, this.Amount, RESERVE_SIZE); + ::ArrayResize(this PTR_DEREF Tickets, this PTR_DEREF Amount, RESERVE_SIZE); - this.RefreshHistory(); + this PTR_DEREF RefreshHistory(); } int GetAmount(void) { - this.RefreshHistory(); + this PTR_DEREF RefreshHistory(); - return ((int)this.Amount); + return ((int)this PTR_DEREF Amount); } long operator[](const uint Pos) { long Res = 0; - if (Pos >= this.Amount) { - this.RefreshHistory(); + if (Pos >= this PTR_DEREF Amount) { + this PTR_DEREF RefreshHistory(); - if (Pos < this.Amount) Res = this.Tickets[Pos]; + if (Pos < this PTR_DEREF Amount) Res = this PTR_DEREF Tickets[Pos]; } else - Res = this.Tickets[Pos]; + Res = this PTR_DEREF Tickets[Pos]; return (Res); } @@ -325,16 +326,19 @@ struct MT4_ORDER { string ToString(void) const { static const string Types[] = {"buy", "sell", "buy limit", "sell limit", "buy stop", "sell stop", "balance"}; - const int digits = (int)::SymbolInfoInteger(this.Symbol, SYMBOL_DIGITS); - - return ("#" + (string)this.Ticket + " " + (string)this.OpenTime + " " + - ((this.Type < ::ArraySize(Types)) ? Types[this.Type] : "unknown") + " " + ::DoubleToString(this.Lots, 2) + - " " + this.Symbol + " " + ::DoubleToString(this.OpenPrice, digits) + " " + - ::DoubleToString(this.StopLoss, digits) + " " + ::DoubleToString(this.TakeProfit, digits) + " " + - ((this.CloseTime > 0) ? ((string)this.CloseTime + " ") : "") + ::DoubleToString(this.ClosePrice, digits) + - " " + ::DoubleToString(this.Commission, 2) + " " + ::DoubleToString(this.Swap, 2) + " " + - ::DoubleToString(this.Profit, 2) + " " + ((this.Comment == "") ? "" : (this.Comment + " ")) + - (string)this.MagicNumber + (((this.Expiration > 0) ? (" expiration " + (string)this.Expiration) : ""))); + const int digits = (int)::SymbolInfoInteger(this PTR_DEREF Symbol, SYMBOL_DIGITS); + + return ( + "#" + (string)this PTR_DEREF Ticket + " " + (string)this PTR_DEREF OpenTime + " " + + ((this PTR_DEREF Type < ::ArraySize(Types)) ? Types[this PTR_DEREF Type] : "unknown") + " " + + ::DoubleToString(this PTR_DEREF Lots, 2) + " " + this PTR_DEREF Symbol + " " + + ::DoubleToString(this PTR_DEREF OpenPrice, digits) + " " + ::DoubleToString(this PTR_DEREF StopLoss, digits) + + " " + ::DoubleToString(this PTR_DEREF TakeProfit, digits) + " " + + ((this PTR_DEREF CloseTime > 0) ? ((string)this PTR_DEREF CloseTime + " ") : "") + + ::DoubleToString(this PTR_DEREF ClosePrice, digits) + " " + ::DoubleToString(this PTR_DEREF Commission, 2) + + " " + ::DoubleToString(this PTR_DEREF Swap, 2) + " " + ::DoubleToString(this PTR_DEREF Profit, 2) + " " + + ((this PTR_DEREF Comment == "") ? "" : (this PTR_DEREF Comment + " ")) + (string)this PTR_DEREF MagicNumber + + (((this PTR_DEREF Expiration > 0) ? (" expiration " + (string)this PTR_DEREF Expiration) : ""))); } }; diff --git a/Mail.mqh b/Mail.mqh index 9ff20a1b1..f41078561 100644 --- a/Mail.mqh +++ b/Mail.mqh @@ -44,10 +44,10 @@ class Mail { * Constructor. */ Mail(string _subject_prefix = "Trading Info: ") { - this.string_dlm = " "; - this.string_nl = "
\n"; - this.subject_execute_order = __FILE__; - this.subject_prefix = _subject_prefix; + this PTR_DEREF string_dlm = " "; + this PTR_DEREF string_nl = "
\n"; + this PTR_DEREF subject_execute_order = __FILE__; + this PTR_DEREF subject_prefix = _subject_prefix; } /* Getters */ @@ -55,12 +55,12 @@ class Mail { /** * Gets subject prefix. */ - string GetMailSubjectPrefix() { return this.subject_prefix; } + string GetMailSubjectPrefix() { return this PTR_DEREF subject_prefix; } /** * Gets subject on execute order. */ - string GetMailSubjectExecuteOrder() { return this.subject_execute_order; } + string GetMailSubjectExecuteOrder() { return this PTR_DEREF subject_execute_order; } /** * Get content of e-mail for executing order. @@ -87,41 +87,45 @@ class Mail { /** * Gets string delimiter. */ - string GetStringDlm() { return this.string_dlm; } + string GetStringDlm() { return this PTR_DEREF string_dlm; } /** * Gets string new line separator. */ - string GetStringNl() { return this.string_nl; } + string GetStringNl() { return this PTR_DEREF string_nl; } /** * Get subject of e-mail for executing order. * * Note: Order needs to be selected before calling this function. */ - string GetSubjectExecuteOrder() { return GetMailSubjectPrefix() + this.string_dlm + GetMailSubjectExecuteOrder(); } + string GetSubjectExecuteOrder() { + return GetMailSubjectPrefix() + this PTR_DEREF string_dlm + GetMailSubjectExecuteOrder(); + } /* Setters */ /** * Sets subject prefix. */ - void SetSubjectPrefix(string _subject_prefix) { this.subject_prefix = _subject_prefix; } + void SetSubjectPrefix(string _subject_prefix) { this PTR_DEREF subject_prefix = _subject_prefix; } /** * Sets subject on execute order. */ - void SetSubjectExecuteOrder(string _subject_execute_order) { this.subject_execute_order = _subject_execute_order; } + void SetSubjectExecuteOrder(string _subject_execute_order) { + this PTR_DEREF subject_execute_order = _subject_execute_order; + } /** * Sets string delimiter. */ - void SetStringDlm(string _dlm) { this.string_dlm = _dlm; } + void SetStringDlm(string _dlm) { this PTR_DEREF string_dlm = _dlm; } /** * Sets string new line separator. */ - void SetStringNl(string _nl) { this.string_nl = _nl; } + void SetStringNl(string _nl) { this PTR_DEREF string_nl = _nl; } /* Mailing methods */ diff --git a/Math.extern.h b/Math.extern.h index 8f575b45b..4dce9bfe7 100644 --- a/Math.extern.h +++ b/Math.extern.h @@ -22,10 +22,28 @@ // Define external global functions. #ifndef __MQL__ -extern double MathAbs(double value); -extern double fabs(double value); +template +extern T MathAbs(T value); +template +extern T fabs(T value); +template +extern T pow(T base, T exponent); +template +extern T MathPow(T base, T exponent); +template +extern T round(T value); +template +extern T MathRound(T value); +template +extern T fmax(T value1, T value2); template extern T MathMax(T value1, T value2); template +extern T fmin(T value1, T value2); +template extern T MathMin(T value1, T value2); +template +extern T MathLog10(T value1); +template +extern T log10(T value); #endif diff --git a/Matrix.mqh b/Matrix.mqh index 069588d7f..59f3eef39 100644 --- a/Matrix.mqh +++ b/Matrix.mqh @@ -1494,8 +1494,9 @@ class Matrix { return NULL; } - if (_weights != NULL && _weights.GetDimensions() > this.GetDimensions()) { - Print("MeanAbsolute(): Shape ", Repr(), ": Weights must be a tensor level <= ", this.GetDimensions(), "!"); + if (_weights != NULL && _weights.GetDimensions() > this PTR_DEREF GetDimensions()) { + Print("MeanAbsolute(): Shape ", Repr(), ": Weights must be a tensor level <= ", this PTR_DEREF GetDimensions(), + "!"); return NULL; } diff --git a/Orders.mqh b/Orders.mqh index 57afd15a5..b245450c4 100644 --- a/Orders.mqh +++ b/Orders.mqh @@ -550,9 +550,9 @@ class Orders { double GetRealizedPL() const { double profit = 0; for (int i = 0; i <= numberOrders; ++i) { - if (this.orders[i].getOrderType() == ORDER_FINAL) { + if (this PTR_DEREF orders[i].getOrderType() == ORDER_FINAL) { // @todo - // profit += this.orders[i].getOrderProfit(); + // profit += this PTR_DEREF orders[i].getOrderProfit(); } } return profit; @@ -569,8 +569,8 @@ class Orders { double GetUnrealizedPL() const { double profit = 0; for (int i = 0; i <= numberOrders; ++i) { - if (this.orders[i].getOrderType() != ORDER_FINAL) { - profit += this.orders[i].getOrderProfit(); + if (this PTR_DEREF orders[i].getOrderType() != ORDER_FINAL) { + profit += this PTR_DEREF orders[i].getOrderProfit(); } } return profit; @@ -579,7 +579,7 @@ class Orders { double GetTotalEquity() const { double profit = 0; for (int i = 0; i <= numberOrders; ++i) { - profit += this.orders[i].GetOrderProfit(); + profit += this PTR_DEREF orders[i].GetOrderProfit(); } return profit; } @@ -587,7 +587,7 @@ class Orders { double GetTotalCommission() const { double commission = 0; for (int i = 0; i <= numberOrders; ++i) { - commission += this.orders[i].GetOrderCommission(); + commission += this PTR_DEREF orders[i].GetOrderCommission(); } return commission; } @@ -595,7 +595,7 @@ class Orders { double GetTotalSwap() const { double swap = 0; for (int i = 0; i <= numberOrders; ++i) { - swap += this.orders[i].GetOrderSwap(); + swap += this PTR_DEREF orders[i].GetOrderSwap(); } return swap; } diff --git a/Refs.mqh b/Refs.mqh index bc71b2138..07b530ff4 100644 --- a/Refs.mqh +++ b/Refs.mqh @@ -25,7 +25,7 @@ #define REFS_MQH // Includes. -#include "Refs.struct.h" +#include "Refs.rc.h" #include "Std.h" /** @@ -66,54 +66,6 @@ // Forward class declaration. class Dynamic; -class ReferenceCounter { - public: - /** - * Number of weak references to target object. - */ - unsigned int num_weak_refs; - - /** - * Number of strong references to target object. - */ - unsigned int num_strong_refs; - - /** - * Target object pointer. - */ - Dynamic* ptr_object; - - /** - * Whether object has been deleted (but still have weak references). - */ - bool deleted; - - /** - * Constructor. - */ - ReferenceCounter() { - num_weak_refs = 0; - num_strong_refs = 0; - ptr_object = NULL; - deleted = false; - } - - string Debug() { return StringFormat("%d: %d strong, %d weak", ptr_object, num_strong_refs, num_weak_refs); } - - /** - * ReferenceCounter class allocator. - */ - 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. */ diff --git a/Refs.rc.h b/Refs.rc.h new file mode 100644 index 000000000..64ec5840c --- /dev/null +++ b/Refs.rc.h @@ -0,0 +1,82 @@ +//+------------------------------------------------------------------+ +//| 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 + * Includes Refs' ReferenceCounter struct. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Forward declarations. +class Dynamic; + +class ReferenceCounter { + public: + /** + * Number of weak references to target object. + */ + unsigned int num_weak_refs; + + /** + * Number of strong references to target object. + */ + unsigned int num_strong_refs; + + /** + * Target object pointer. + */ + Dynamic* ptr_object; + + /** + * Whether object has been deleted (but still have weak references). + */ + bool deleted; + + /** + * Constructor. + */ + ReferenceCounter() { + num_weak_refs = 0; + num_strong_refs = 0; + ptr_object = NULL; + deleted = false; + } + + string Debug() { return StringFormat("%d: %d strong, %d weak", ptr_object, num_strong_refs, num_weak_refs); } + + /** + * ReferenceCounter class allocator. + */ + static ReferenceCounter* alloc(); +}; + +/** + * ReferenceCounter class allocator. + */ +ReferenceCounter* ReferenceCounter::alloc() { + // @todo Enhance with linked-list object reuse. + return new ReferenceCounter(); +} \ No newline at end of file diff --git a/Refs.struct.h b/Refs.struct.h index e06998fa9..21f5d43c1 100644 --- a/Refs.struct.h +++ b/Refs.struct.h @@ -31,11 +31,11 @@ #endif // Includes. +#include "Refs.rc.h" #include "Std.h" +class Dynamic; // Forward class declaration. -class Refs; -class ReferenceCounter; template struct WeakRef; @@ -322,16 +322,18 @@ struct WeakRef { if (!PTR_ATTRIB(ptr_ref_counter, num_strong_refs)) { // There are also no strong references. ReferenceCounter* stored_ptr_ref_counter = ptr_ref_counter; - if (!ptr_ref_counter.deleted) { + if (!ptr_ref_counter PTR_DEREF deleted) { // It is safe to delete object and reference counter object. // Avoiding double deletion in Dynamic's destructor. - ptr_ref_counter.ptr_object.ptr_ref_counter = NULL; + ptr_ref_counter PTR_DEREF ptr_object PTR_DEREF ptr_ref_counter = NULL; #ifdef __debug__ Print("Refs: Deleting object ", ptr_ref_counter.ptr_object); #endif - if (CheckPointer(ptr_ref_counter.ptr_object) == POINTER_INVALID) { +#ifdef __MQL__ + // We can't check pointer validity in C++ (other than check for NULL). + if (CheckPointer(ptr_ref_counter PTR_DEREF ptr_object) == POINTER_INVALID) { // Serious problem. #ifndef __MQL4__ // Bug: Avoid calling in MQL4 due to 'global initialization failed' error. @@ -339,10 +341,12 @@ struct WeakRef { #endif return; } - - delete ptr_ref_counter.ptr_object; +#endif + delete ptr_ref_counter PTR_DEREF ptr_object; } +#ifdef __MQL__ + // We can't check pointer validity in C++ (other than check for NULL). if (CheckPointer(stored_ptr_ref_counter) == POINTER_INVALID) { // Serious problem. #ifndef __MQL4__ @@ -351,6 +355,7 @@ struct WeakRef { #endif return; } +#endif delete stored_ptr_ref_counter; } diff --git a/Serializer.mqh b/Serializer.mqh index 006839a67..40abac3d1 100644 --- a/Serializer.mqh +++ b/Serializer.mqh @@ -28,13 +28,15 @@ #include "Convert.mqh" #include "Serializer.define.h" #include "Serializer.enum.h" -#include "SerializerConverter.mqh" #include "SerializerNode.mqh" -#include "SerializerNodeIterator.mqh" #include "SerializerNodeParam.mqh" #define SERIALIZER_DEFAULT_FP_PRECISION 8 +// Forward declarations. +template +class SerializerIterator; + class Serializer { protected: SerializerNode* _node; @@ -71,10 +73,7 @@ class Serializer { } template - SerializerIterator Begin() { - SerializerIterator iter(THIS_PTR, _node); - return iter; - } + SerializerIterator Begin(); void FreeRootNodeOwnership() { _root_node_ownership = false; } @@ -200,9 +199,9 @@ class Serializer { value.Serialize(this); fp_precision = SERIALIZER_DEFAULT_FP_PRECISION; - SerializerNode* obj = _node.GetChild(_node.NumChildren() - 1); + SerializerNode* obj = _node PTR_DEREF GetChild(PTR_ATTRIB(_node, NumChildren()) - 1); - obj.SetKey(name); + obj PTR_DEREF SetKey(name); } else { _single_value_name = name; value.Serialize(this); @@ -345,7 +344,7 @@ class Serializer { if (si.HasKey()) { // Should not happen. } else { - _node = parent.GetChild(si.Index()); + _node = parent PTR_DEREF GetChild(si.Index()); array[si.Index()] = si.Struct(); } } @@ -431,19 +430,12 @@ class Serializer { return NULL; } - - 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) { - if (_serializer_flags == 0) { - // Avoiding flags misuse. - _serializer_flags = SERIALIZER_FLAG_INCLUDE_ALL; - } - - X stub; - stub.SerializeStub(_n1, _n2, _n3, _n4, _n5); - return SerializerConverter::FromObject(stub, _serializer_flags); - } }; +template +SerializerIterator Serializer::Begin() { + SerializerIterator iter(THIS_PTR, _node); + return iter; +} + #endif // End: SERIALIZER_MQH diff --git a/SerializerConverter.mqh b/SerializerConverter.mqh index f22b77f03..c14e3c628 100644 --- a/SerializerConverter.mqh +++ b/SerializerConverter.mqh @@ -23,6 +23,7 @@ // Prevents processing this includes file for the second time. #ifndef SERIALIZER_CONVERTER_MQH #define SERIALIZER_CONVERTER_MQH +#include "SerializerDict.mqh" // Forward declarations. class SerializerNode; @@ -30,6 +31,7 @@ class SerializerNode; // Includes. #include "File.mqh" #include "Serializer.enum.h" +#include "Serializer.mqh" #include "SerializerNode.mqh" class SerializerConverter { diff --git a/SerializerDict.mqh b/SerializerDict.mqh index 68ebde3fc..ddef3e957 100644 --- a/SerializerDict.mqh +++ b/SerializerDict.mqh @@ -33,16 +33,16 @@ class SerializerDict { public: template static void Extract(SerializerNode* _root, D& _dict, unsigned int extractor_flags = 0) { - if (_root.IsContainer()) { - for (unsigned int _data_entry_idx = 0; _data_entry_idx < _root.NumChildren(); ++_data_entry_idx) { - Extract(_root.GetChild(_data_entry_idx), _dict, extractor_flags); + if (_root PTR_DEREF IsContainer()) { + for (unsigned int _data_entry_idx = 0; _data_entry_idx < _root PTR_DEREF NumChildren(); ++_data_entry_idx) { + Extract(_root PTR_DEREF GetChild(_data_entry_idx), _dict, extractor_flags); } } else { - SerializerNodeParam* _value_param = _root.GetValueParam(); + SerializerNodeParam* _value_param = _root PTR_DEREF GetValueParam(); V _aux = (V)NULL; - _dict.Push(_value_param.ConvertTo(_aux)); + _dict.Push(_value_param PTR_DEREF ConvertTo(_aux)); } } }; diff --git a/SerializerJson.mqh b/SerializerJson.mqh index 8465f82c2..d9ea025a4 100644 --- a/SerializerJson.mqh +++ b/SerializerJson.mqh @@ -118,9 +118,7 @@ class SerializerJson { return false; } - Serializer serializer(node, JsonUnserialize); - - if (logger != NULL) serializer.Logger().Link(logger); + Serializer serializer(node, Unserialize); // We don't use result. We parse data as it is. obj.Serialize(serializer); diff --git a/SerializerNodeIterator.mqh b/SerializerNodeIterator.mqh index ad3b29c9a..57acc5265 100644 --- a/SerializerNodeIterator.mqh +++ b/SerializerNodeIterator.mqh @@ -24,6 +24,7 @@ #ifndef JSON_ITERATOR_MQH #define JSON_ITERATOR_MQH +#include "Serializer.mqh" #include "SerializerNode.mqh" class SerializerNode; diff --git a/Std.h b/Std.h index 2a915fb92..a80ec9fe6 100644 --- a/Std.h +++ b/Std.h @@ -203,6 +203,12 @@ class color { const char* cstring_from(const std::string& _value) { return _value.c_str(); } #endif +#ifdef __cplusplus +using std::string; +#endif + +bool IsNull(const string& str) { return str == ""; } + /** * Referencing struct's enum. * diff --git a/String.extern.h b/String.extern.h index 47a6ff3e3..04f359fef 100644 --- a/String.extern.h +++ b/String.extern.h @@ -23,6 +23,7 @@ // Prevents processing this includes file for the second time. #ifndef __MQL__ #pragma once +#include "Terminal.define.h" #endif // Define external global functions. @@ -36,4 +37,6 @@ extern string IntegerToString(long number, int str_len = 0, ushort fill_symbol = extern string StringFormat(string format, ...); extern string StringSubstr(string string_value, int start_pos, int length = -1); extern ushort StringGetCharacter(string string_value, int pos); +int StringToCharArray(string text_string, ARRAY_REF(uchar, array), int start = 0, int count = -1, + uint codepage = CP_ACP); #endif diff --git a/SymbolInfo.static.h b/SymbolInfo.static.h index cf5d7f2bf..85a4fbf26 100644 --- a/SymbolInfo.static.h +++ b/SymbolInfo.static.h @@ -138,7 +138,8 @@ class SymbolInfoStatic { * See: http://forum.mql4.com/30672 */ static unsigned int GetPointsPerPip(string _symbol) { - return (unsigned int)pow(10, SymbolInfoStatic::GetDigits(_symbol) - SymbolInfoStatic::GetPipDigits(_symbol)); + return (unsigned int)pow((unsigned int)10, + SymbolInfoStatic::GetDigits(_symbol) - SymbolInfoStatic::GetPipDigits(_symbol)); } /** @@ -264,7 +265,7 @@ class SymbolInfoStatic { * Get real spread based on the ask and bid price (in points). */ static unsigned int GetRealSpread(double _bid, double _ask, unsigned int _digits) { - return (unsigned int)round((_ask - _bid) * pow(10, _digits)); + return (unsigned int)round((_ask - _bid) * pow((unsigned int)10, _digits)); } static unsigned int GetRealSpread(string _symbol) { return GetRealSpread(SymbolInfoStatic::GetBid(_symbol), SymbolInfoStatic::GetAsk(_symbol), diff --git a/Ticker.mqh b/Ticker.mqh index 0e56e424d..a02bccd5c 100644 --- a/Ticker.mqh +++ b/Ticker.mqh @@ -145,7 +145,7 @@ class Ticker { return true; } bool Add() { - MqlTick _tick = this.symbol.GetTick(); + MqlTick _tick = this PTR_DEREF symbol.GetTick(); return Add(_tick); } @@ -172,8 +172,8 @@ class Ticker { FileWrite(_handle, "Datatime", "Bid", "Ask", "Volume"); for (int i = 0; i < index; i++) { if (data[i].time > 0) { - FileWrite(_handle, DateTimeStatic::TimeToStr(data[i].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS), data[i].bid, - data[i].ask, data[i].volume); + FileWrite(_handle, DateTimeStatic::TimeToStr(data[i].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS), + data[i].bid, data[i].ask, data[i].volume); total_saved++; } } diff --git a/Timer.mqh b/Timer.mqh index e772306d7..986556b08 100644 --- a/Timer.mqh +++ b/Timer.mqh @@ -28,140 +28,115 @@ * Class to provide functions to deal with the timer. */ class Timer : public Object { - - protected: - - // Variables. - string name; - int index; - uint data[]; - uint start, end; - ulong max; - - public: - - /** - * Class constructor. - */ - Timer(string _name = "") : index(-1), name(_name) { }; - - /* Main methods */ - - /** - * Start the timer. - */ - void Start() { - start = GetTickCount(); - } - - /** - * Stop the timer. - */ - Timer *Stop() { - end = GetTickCount(); - ArrayResize(this.data, ++this.index + 1, 10000); - data[this.index] = fabs(this.end - this.start); - max = fmax(data[this.index], this.max); - return GetPointer(this); - } - - /* Misc */ - - /** - * Print the current timer times. - */ - Timer *PrintSummary() { - Print(ToString()); - return GetPointer(this); - } - - /** - * Print the current timer times when maximum value is reached. - */ - Timer *PrintOnMax(ulong _min = 1) { - return - data[index] > _min && data[this.index] >= this.max - ? PrintSummary() - : GetPointer(this); - } - - /* Getters */ - - /** - * Stop the timer. - */ - uint GetTime(uint _index) { - return data[_index]; + protected: + // Variables. + string name; + int index; + uint data[]; + uint start, end; + ulong max; + + public: + /** + * Class constructor. + */ + Timer(string _name = "") : index(-1), name(_name){}; + + /* Main methods */ + + /** + * Start the timer. + */ + void Start() { start = GetTickCount(); } + + /** + * Stop the timer. + */ + Timer *Stop() { + end = GetTickCount(); + ArrayResize(this PTR_DEREF data, ++this PTR_DEREF index + 1, 10000); + data[this PTR_DEREF index] = fabs(this PTR_DEREF end - this PTR_DEREF start); + max = fmax(data[this PTR_DEREF index], this PTR_DEREF max); + return GetPointer(this); + } + + /* Misc */ + + /** + * Print the current timer times. + */ + Timer *PrintSummary() { + Print(ToString()); + return GetPointer(this); + } + + /** + * Print the current timer times when maximum value is reached. + */ + Timer *PrintOnMax(ulong _min = 1) { + return data[index] > _min && data[this PTR_DEREF index] >= this PTR_DEREF max ? PrintSummary() : GetPointer(this); + } + + /* Getters */ + + /** + * Stop the timer. + */ + uint GetTime(uint _index) { return data[_index]; } + uint GetTime() { return GetTickCount() - this PTR_DEREF start; } + + /** + * Returns timer name. + */ + string GetName() { return this PTR_DEREF name; } + + /** + * Get the sum of all values. + */ + ulong GetSum() { + uint _size = ArraySize(this PTR_DEREF data); + ulong _sum = 0; + for (uint _i = 0; _i < _size; _i++) { + _sum += data[_i]; } - uint GetTime() { - return GetTickCount() - this.start; + return _sum; + } + + /** + * Get the median of all values. + */ + uint GetMedian() { + if (this PTR_DEREF index >= 0) { + ArraySort(this PTR_DEREF data); } - - /** - * Returns timer name. - */ - string GetName() { - return this.name; - } - - /** - * Get the sum of all values. - */ - ulong GetSum() { - uint _size = ArraySize(this.data); - ulong _sum = 0; - for (uint _i = 0; _i < _size; _i++) { - _sum += data[_i]; - } - return _sum; - } - - /** - * Get the median of all values. - */ - uint GetMedian() { - if (this.index >= 0) { - ArraySort(this.data); - } - return this.index >= 0 ? this.data[this.index / 2] : 0; - } - - /** - * Get the minimum time value. - */ - uint GetMin() { - return this.index >= 0 ? this.data[ArrayMinimum(this.data)] : 0; - } - - /** - * Get the maximal time value. - */ - uint GetMax() { - int _index = this.index >= 0 ? ArrayMaximum(this.data) : -1; - return _index >= 0 ? data[_index] : 0; - } - - /* Inherited methods */ - - /** - * Print timer times. - */ - virtual const string ToString() { - return StringFormat("%s(%d)=%d-%dms,med=%dms,sum=%dms", - GetName(), - ArraySize(this.data), - GetMin(), - GetMax(), - GetMedian(), - GetSum() - ); - } - - /** - * Returns weight of the object. - */ - virtual double GetWeight() { - return (double) GetSum(); - } - + return this PTR_DEREF index >= 0 ? this PTR_DEREF data[this PTR_DEREF index / 2] : 0; + } + + /** + * Get the minimum time value. + */ + uint GetMin() { return this PTR_DEREF index >= 0 ? this PTR_DEREF data[ArrayMinimum(this PTR_DEREF data)] : 0; } + + /** + * Get the maximal time value. + */ + uint GetMax() { + int _index = this PTR_DEREF index >= 0 ? ArrayMaximum(this PTR_DEREF data) : -1; + return _index >= 0 ? data[_index] : 0; + } + + /* Inherited methods */ + + /** + * Print timer times. + */ + virtual const string ToString() { + return StringFormat("%s(%d)=%d-%dms,med=%dms,sum=%dms", GetName(), ArraySize(this PTR_DEREF data), GetMin(), + GetMax(), GetMedian(), GetSum()); + } + + /** + * Returns weight of the object. + */ + virtual double GetWeight() { return (double)GetSum(); } }; diff --git a/Trade/TradeSignal.struct.h b/Trade/TradeSignal.struct.h index 48661c5a5..a55206c84 100644 --- a/Trade/TradeSignal.struct.h +++ b/Trade/TradeSignal.struct.h @@ -27,7 +27,6 @@ // Includes. #include "../Chart.enum.h" -#include "../Serializer.mqh" #include "../SerializerConverter.mqh" #include "../SerializerJson.mqh" From 98f7b4eedeccc7fb3a49ee0bbcc588fb8ee1f1fd Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Fri, 21 Jan 2022 14:47:08 +0100 Subject: [PATCH 72/81] Working compilation via GCC for TradeSignal.test.cpp and TradeSignalManager.test.cpp. --- Account.struct.h | 1 + Array.mqh | 2 +- Chart.struct.tf.h | 1 + Common.define.h | 1 + Convert.mqh | 14 +- DictBase.mqh | 2 +- DictObject.mqh | 14 +- EA.mqh | 9 +- Math.define.h | 22 ++++ Object.mqh | 215 ++++++++++++++----------------- Order.mqh | 4 +- Refs.rc.h | 2 +- Serializer.mqh | 12 +- SerializerConversions.h | 1 + SerializerJson.mqh | 19 ++- SerializerNode.mqh | 19 ++- Std.h | 9 +- String.mqh | 1 + Trade/tests/TradeSignal.test.cpp | 4 +- tests/BufferStructTest.mq5 | 1 + tests/SerializerTest.mq5 | 4 +- 21 files changed, 196 insertions(+), 161 deletions(-) diff --git a/Account.struct.h b/Account.struct.h index 5e0e03e22..61b954ab5 100644 --- a/Account.struct.h +++ b/Account.struct.h @@ -36,6 +36,7 @@ class Serializer; // Includes. #include "Serializer.mqh" +#include "Terminal.define.h" // Struct for account entries. struct AccountEntry { diff --git a/Array.mqh b/Array.mqh index 1a07d3fc0..d71b044d0 100644 --- a/Array.mqh +++ b/Array.mqh @@ -544,7 +544,7 @@ static int GetLowestArrDoubleValue(double& arr[][], int key) { #else int i; string output = ""; - for (i = _start; i < _count == WHOLE_ARRAY ? ArraySize(_arr) : _count; i++) { + for (i = _start; i < (_count == WHOLE_ARRAY ? ArraySize(_arr) : _count); i++) { output += (string)_arr[i] + _dlm; } Print(output); diff --git a/Chart.struct.tf.h b/Chart.struct.tf.h index 6c91b1c16..d72b039fd 100644 --- a/Chart.struct.tf.h +++ b/Chart.struct.tf.h @@ -32,6 +32,7 @@ // Includes. #include "Chart.enum.h" +#include "Terminal.define.h" /* Defines struct for chart timeframe. */ struct ChartTf { diff --git a/Common.define.h b/Common.define.h index b0daac762..09f7d754a 100644 --- a/Common.define.h +++ b/Common.define.h @@ -26,6 +26,7 @@ */ #ifndef __MQL__ // Data types. +#include typedef std::string string; typedef unsigned char uchar; typedef unsigned int uint; diff --git a/Convert.mqh b/Convert.mqh index c6d52ab38..a3fec14bb 100644 --- a/Convert.mqh +++ b/Convert.mqh @@ -67,7 +67,7 @@ class Convert { case ORDER_TYPE_BUY_STOP: return ORDER_TYPE_BUY; default: - return (ENUM_ORDER_TYPE)-1; + return InvalidEnumValue::value(); } } @@ -82,7 +82,7 @@ class Convert { * Returns OP_BUY when value is positive, OP_SELL when negative, otherwise -1. */ static ENUM_ORDER_TYPE ValueToOp(int value) { - return value == 0 ? (ENUM_ORDER_TYPE)-1 : (value > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL); + return value == 0 ? InvalidEnumValue::value() : (value > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL); } /** @@ -96,7 +96,7 @@ class Convert { * Returns OP_BUY when value is positive, OP_SELL when negative, otherwise -1. */ static ENUM_ORDER_TYPE ValueToOp(double value) { - return value == 0 ? (ENUM_ORDER_TYPE)-1 : (value > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL); + return value == 0 ? InvalidEnumValue::value() : (value > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL); } /** @@ -181,19 +181,19 @@ class Convert { switch (mode) { case 0: // Forex. // In currencies a tick is a point. - return pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); + return (double)pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); case 1: // CFD. // In metals a Tick is still the smallest change, but is larger than a point. // If price can change from 123.25 to 123.50, // you have a TickSize of 0.25 and a point of 0.01. Pip has no meaning. // @todo - return pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); + return (double)pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); case 2: // Futures. // @todo - return pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); + return (double)pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); case 3: // CFD for indices. // @todo - return pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); + return (double)pts * SymbolInfoStatic::SymbolInfoDouble(_symbol, SYMBOL_TRADE_TICK_SIZE); } return false; } diff --git a/DictBase.mqh b/DictBase.mqh index 5c3ab43e5..62a2a1432 100644 --- a/DictBase.mqh +++ b/DictBase.mqh @@ -204,7 +204,7 @@ class DictBase { if (_DictSlots_ref.DictSlots[position].IsUsed()) { if (GetMode() == DictModeList) { - _should_be_removed = position == (int)key; + _should_be_removed = position == (unsigned int)key; } else { _should_be_removed = _DictSlots_ref.DictSlots[position].HasKey() && _DictSlots_ref.DictSlots[position].key == key; diff --git a/DictObject.mqh b/DictObject.mqh index fd1e75b9a..36027b8ed 100644 --- a/DictObject.mqh +++ b/DictObject.mqh @@ -231,7 +231,7 @@ class DictObject : public DictBase { position = this PTR_DEREF Hash(key) % ArraySize(dictSlotsRef.DictSlots); unsigned int _starting_position = position; - int _num_conflicts = 0; + unsigned int _num_conflicts = 0; bool _overwrite_slot = false; // Searching for empty DictSlot or used one with the matching key. It skips used, hashless DictSlots. @@ -363,8 +363,10 @@ class DictObject : public DictBase { #endif SerializerNodeType Serialize(Serializer& s) { if (s.IsWriting()) { - for (DictIteratorBase i(Begin()); i.IsValid(); ++i) - s.PassObject(THIS_REF, this PTR_DEREF GetMode() == DictModeDict ? i.KeyAsString() : "", i.Value()); + for (DictObjectIterator i(Begin()); i.IsValid(); ++i) { + V* _value = i.Value(); + s.PassObject(THIS_REF, this PTR_DEREF GetMode() == DictModeDict ? i.KeyAsString() : "", PTR_TO_REF(_value)); + } return (this PTR_DEREF GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray; } else { @@ -395,9 +397,11 @@ class DictObject : public DictBase { // Note that we're retrieving value by a key (as we are in an // object!). - Set(key, i.Struct(i.Key())); + V _prop = i.Struct(i.Key()); + Set(key, _prop); } else { - Push(i.Struct()); + V _prop = i.Struct(); + Push(_prop); } } return i.ParentNodeType(); diff --git a/EA.mqh b/EA.mqh index e74822cf8..5346c0328 100644 --- a/EA.mqh +++ b/EA.mqh @@ -512,7 +512,7 @@ class EA { string _key_chart = "Chart"; _key_chart += StringFormat("-%d-%d", data_chart.GetMin(), data_chart.GetMax()); - SerializerConverter _stub = Serializer::MakeStubObject>(_serializer_flags); + SerializerConverter _stub = SerializerConverter::MakeStubObject>(_serializer_flags); SerializerConverter _obj = SerializerConverter::FromObject(data_chart, _serializer_flags); if ((_methods & EA_DATA_EXPORT_CSV) != 0) { @@ -532,7 +532,8 @@ class EA { _obj.Clean(); } if (eparams.CheckFlagDataStore(EA_DATA_STORE_INDICATOR)) { - SerializerConverter _stub = Serializer::MakeStubObject>(_serializer_flags); + SerializerConverter _stub = + SerializerConverter::MakeStubObject>(_serializer_flags); /* for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { @@ -567,7 +568,7 @@ class EA { _stub.Clean(); } if (eparams.CheckFlagDataStore(EA_DATA_STORE_STRATEGY)) { - SerializerConverter _stub = Serializer::MakeStubObject>(_serializer_flags); + SerializerConverter _stub = SerializerConverter::MakeStubObject>(_serializer_flags); /* @fixme for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { @@ -597,7 +598,7 @@ class EA { _stub.Clean(); } if (eparams.CheckFlagDataStore(EA_DATA_STORE_SYMBOL)) { - SerializerConverter _stub = Serializer::MakeStubObject>(_serializer_flags); + SerializerConverter _stub = SerializerConverter::MakeStubObject>(_serializer_flags); SerializerConverter _obj = SerializerConverter::FromObject(data_symbol, _serializer_flags); string _key_sym = "Symbol"; diff --git a/Math.define.h b/Math.define.h index 82ac071dd..8402d7a5e 100644 --- a/Math.define.h +++ b/Math.define.h @@ -36,3 +36,25 @@ #define fmin4(_v1, _v2, _v3, _v4) fmin(fmin(fmin(_v1, _v2), _v3), _v4) #define fmin5(_v1, _v2, _v3, _v4, _v5) fmin(fmin(fmin(fmin(_v1, _v2), _v3), _v4), _v5) #define fmin6(_v1, _v2, _v3, _v4, _v5, _v6) fmin(fmin(fmin(fmin(fmin(_v1, _v2), _v3), _v4), _v5), _v6) + +#ifdef __cplusplus +#include + +#define CHAR_MIN std::numeric_limits::min() +#define CHAR_MAX std::numeric_limits::max() +#define UCHAR_MAX std::numeric_limits::max() +#define SHORT_MAX std::numeric_limits::max() +#define SHORT_MIN std::numeric_limits::min() +#define USHORT_MAX std::numeric_limits::max() +#define INT_MIN std::numeric_limits::min() +#define INT_MAX std::numeric_limits::max() +#define UINT_MAX std::numeric_limits::max() +#define LONG_MIN std::numeric_limits::min() +#define LONG_MAX std::numeric_limits::max() +#define ULONG_MAX std::numeric_limits::max() +#define FLT_MIN std::numeric_limits::min() +#define FLT_MAX std::numeric_limits::max() +#define DBL_MIN std::numeric_limits::min() +#define DBL_MAX std::numeric_limits::max() + +#endif \ No newline at end of file diff --git a/Object.mqh b/Object.mqh index 86897917a..ecbfcece3 100644 --- a/Object.mqh +++ b/Object.mqh @@ -28,133 +28,112 @@ #include "Object.enum.h" #include "Object.extern.h" #include "Refs.mqh" +#include "Refs.struct.h" #include "String.mqh" /** * Class to deal with objects. */ class Object : public Dynamic { - - protected: - - void *obj; - long id; - - public: - - /** - * Class constructor. - */ - Object() - : id(rand()), obj(THIS_PTR) - { - } - Object(void *_obj, long _id = __LINE__) { - obj = _obj; - id = _id; - } - - /* Getters */ - - /** - * Get ID of the object. - */ - virtual long GetId() { - return id; - } - - /* Setters */ - - /** - * Set ID of the object. - */ - void SetId(long _id) { - id = _id; - } - - /** - * Get the object handler. - */ - static void *Get(void *_obj) { - return Object::IsValid(_obj) ? _obj : NULL; - } - void *Get() { - return IsValid(obj) ? obj : NULL; + protected: + void *obj; + long id; + + public: + /** + * Class constructor. + */ + Object() : id(rand()), obj(THIS_PTR) {} + Object(void *_obj, long _id = __LINE__) { + obj = _obj; + id = _id; + } + + /* Getters */ + + /** + * Get ID of the object. + */ + virtual long GetId() { return id; } + + /* Setters */ + + /** + * Set ID of the object. + */ + void SetId(long _id) { id = _id; } + + /** + * Get the object handler. + */ + static void *Get(void *_obj) { return Object::IsValid(_obj) ? _obj : NULL; } + void *Get() { return IsValid(obj) ? obj : NULL; } + + /** + * Check whether pointer is valid. + * @docs: https://docs.mql4.com/constants/namedconstants/enum_pointer_type + */ + static bool IsValid(void *_obj) { +#ifdef __MQL__ + return CheckPointer(_obj) != POINTER_INVALID; +#else + return _obj != nullptr; +#endif + } + bool IsValid() { return IsValid(obj); } + + /** + * Check whether pointer is dynamic. + * @docs: https://docs.mql4.com/constants/namedconstants/enum_pointer_type + */ + static bool IsDynamic(void *_obj) { +#ifdef __MQL__ + return CheckPointer(_obj) == POINTER_DYNAMIC; +#else + // In C++ we can't check it. + // @fixme We should fire a warning here so user won't use this method anymore. + return true; +#endif + } + bool IsDynamic() { return IsDynamic(obj); } + + /** + * Returns text representation of the object. + */ + virtual const string ToString() { return StringFormat("[Object #%04x]", GetPointer(this)); } + + /** + * Returns text representation of the object. + */ + virtual const string ToJSON() { return StringFormat("{ \"type\": \"%s\" }", typename(this)); } + + /** + * Safely delete the object. + */ +#ifdef __cplusplus + template + static void Delete(T *_obj) { +#else + static void Delete(void *_obj) { +#endif +#ifdef __MQL__ + if (CheckPointer(_obj) == POINTER_DYNAMIC) { +#else + if (true) { +#endif + delete _obj; } + } + void Delete() { Delete(obj); } - /** - * Check whether pointer is valid. - * @docs: https://docs.mql4.com/constants/namedconstants/enum_pointer_type - */ - static bool IsValid(void *_obj) { - #ifdef __MQL__ - return CheckPointer(_obj) != POINTER_INVALID; - #else - return _obj != nullptr; - #endif - } - bool IsValid() { - return IsValid(obj); - } - - /** - * Check whether pointer is dynamic. - * @docs: https://docs.mql4.com/constants/namedconstants/enum_pointer_type - */ - static bool IsDynamic(void *_obj) { - #ifdef __MQL__ - return CheckPointer(_obj) == POINTER_DYNAMIC; - #else - // In C++ we can't check it. - // @fixme We should fire a warning here so user won't use this method anymore. - return true; - #endif - } - bool IsDynamic() { - return IsDynamic(obj); - } - - /** - * Returns text representation of the object. - */ - virtual const string ToString() { - return StringFormat("[Object #%04x]", GetPointer(this)); - } - - /** - * Returns text representation of the object. - */ - virtual const string ToJSON() { - return StringFormat("{ \"type\": \"%s\" }", typename(this)); - } - - /** - * Safely delete the object. - */ - static void Delete(void *_obj) { - #ifdef __MQL__ - if (CheckPointer(_obj) == POINTER_DYNAMIC) { - #else - if (true) { - #endif - delete _obj; - } - } - void Delete() { - Delete(obj); - } - - /* Virtual methods */ - - /** - * Weight of the object. - */ - virtual double GetWeight() { - return 0; - }; + /* Virtual methods */ + /** + * Weight of the object. + */ + virtual double GetWeight() { return 0; }; }; // Initialize static global variables. -//Object *Object::list = { 0 }; -#endif // OBJECT_MQH +// Object *Object::list = { 0 }; +#endif // OBJECT_MQH diff --git a/Order.mqh b/Order.mqh index 10f8b57a8..cf6882ebb 100644 --- a/Order.mqh +++ b/Order.mqh @@ -39,7 +39,7 @@ #include "Order.define.h" #include "Order.enum.h" #include "Order.struct.h" -#include "Serializer.mqh" +#include "SerializerConverter.mqh" #include "SerializerJson.mqh" #include "Std.h" #include "String.mqh" @@ -2735,7 +2735,7 @@ class Order : public SymbolInfo { * Returns order details in text. */ string const ToString() { - SerializerConverter stub(Serializer::MakeStubObject(SERIALIZER_FLAG_SKIP_HIDDEN)); + SerializerConverter stub(SerializerConverter::MakeStubObject(SERIALIZER_FLAG_SKIP_HIDDEN)); return SerializerConverter::FromObject(THIS_REF, SERIALIZER_FLAG_SKIP_HIDDEN) .ToString(SERIALIZER_FLAG_SKIP_HIDDEN, &stub); } diff --git a/Refs.rc.h b/Refs.rc.h index 64ec5840c..c24c32b0f 100644 --- a/Refs.rc.h +++ b/Refs.rc.h @@ -79,4 +79,4 @@ class ReferenceCounter { ReferenceCounter* ReferenceCounter::alloc() { // @todo Enhance with linked-list object reuse. return new ReferenceCounter(); -} \ No newline at end of file +} diff --git a/Serializer.mqh b/Serializer.mqh index 40abac3d1..533aff32c 100644 --- a/Serializer.mqh +++ b/Serializer.mqh @@ -29,6 +29,7 @@ #include "Serializer.define.h" #include "Serializer.enum.h" #include "SerializerNode.mqh" +#include "SerializerNodeIterator.mqh" #include "SerializerNodeParam.mqh" #define SERIALIZER_DEFAULT_FP_PRECISION 8 @@ -73,7 +74,10 @@ class Serializer { } template - SerializerIterator Begin(); + SerializerIterator Begin() { + SerializerIterator iter(THIS_PTR, _node); + return iter; + } void FreeRootNodeOwnership() { _root_node_ownership = false; } @@ -432,10 +436,4 @@ class Serializer { } }; -template -SerializerIterator Serializer::Begin() { - SerializerIterator iter(THIS_PTR, _node); - return iter; -} - #endif // End: SERIALIZER_MQH diff --git a/SerializerConversions.h b/SerializerConversions.h index 8ca443963..46568b7fa 100644 --- a/SerializerConversions.h +++ b/SerializerConversions.h @@ -30,6 +30,7 @@ #pragma once #endif +#include "Convert.extern.h" #include "DateTime.extern.h" #include "Object.mqh" #include "Refs.struct.h" diff --git a/SerializerJson.mqh b/SerializerJson.mqh index d9ea025a4..1e87e3481 100644 --- a/SerializerJson.mqh +++ b/SerializerJson.mqh @@ -79,6 +79,12 @@ class SerializerJson { case SerializerNodeArray: repr += string("[") + (trimWhitespaces ? "" : "\n"); break; + case SerializerNodeUnknown: + case SerializerNodeValue: + case SerializerNodeObjectProperty: + case SerializerNodeArrayItem: + break; + default:; } if (PTR_ATTRIB(_node, HasChildren())) { @@ -94,6 +100,11 @@ class SerializerJson { case SerializerNodeArray: repr += ident + "]"; break; + case SerializerNodeUnknown: + case SerializerNodeValue: + case SerializerNodeObjectProperty: + case SerializerNodeArrayItem: + default:; } if (!PTR_ATTRIB(_node, IsLast())) repr += ","; @@ -127,11 +138,10 @@ class SerializerJson { } static SerializerNode* Parse(string data, unsigned int converter_flags = 0) { - SerializerNodeType type; if (StringGetCharacter(data, 0) == '{') - type = SerializerNodeObject; + ; else if (StringGetCharacter(data, 0) == '[') - type = SerializerNodeArray; + ; else { return GracefulReturn("Failed to parse JSON. It must start with either \"{\" or \"[\".", 0, NULL, NULL); } @@ -142,7 +152,6 @@ class SerializerJson { string extracted; - bool isOuterScope = true; bool expectingKey = false; bool expectingValue = false; bool expectingSemicolon = false; @@ -218,7 +227,6 @@ class SerializerJson { current = node; - isOuterScope = false; expectingValue = false; expectingKey = ch2 != '}'; key = NULL; @@ -252,7 +260,6 @@ class SerializerJson { current = node; expectingValue = ch2 != ']'; - isOuterScope = false; key = NULL; } else if (ch == ']') { #ifdef __debug__ diff --git a/SerializerNode.mqh b/SerializerNode.mqh index 5d347aad4..9edec07e7 100644 --- a/SerializerNode.mqh +++ b/SerializerNode.mqh @@ -25,6 +25,7 @@ #define JSON_NODE_MQH // Includes. +#include "Math.extern.h" #include "SerializerNode.enum.h" #include "SerializerNodeParam.mqh" @@ -81,8 +82,7 @@ class SerializerNode { /** * Checks whether node has specified key. */ - bool HasKey() { return _key != NULL && PTR_ATTRIB(_key, _string) != ""; - } + bool HasKey() { return _key != NULL && PTR_ATTRIB(_key, _string) != ""; } /** * Checks whether node is an array. @@ -211,7 +211,8 @@ class SerializerNode { } for (unsigned int i = 0; i < _numChildren; ++i) { - if (PTR_ATTRIB(_children[i], GetType()) == SerializerNodeArray || PTR_ATTRIB(_children[i], GetType()) == SerializerNodeObject) { + if (PTR_ATTRIB(_children[i], GetType()) == SerializerNodeArray || + PTR_ATTRIB(_children[i], GetType()) == SerializerNodeObject) { _sum += PTR_ATTRIB(_children[i], MaximumNumContainersInDeepEnd()); } } @@ -257,7 +258,7 @@ class SerializerNode { * Adds child to this node. */ void AddChild(SerializerNode* child) { - if (_numChildren == ArraySize(_children)) ArrayResize(_children, _numChildren + 10); + if (_numChildren == (unsigned int)ArraySize(_children)) ArrayResize(_children, _numChildren + 10); PTR_ATTRIB(child, _index) = (int)_numChildren; _children[_numChildren++] = child; @@ -326,6 +327,11 @@ class SerializerNode { case SerializerNodeArray: repr += string("[") + (trimWhitespaces ? "" : "\n"); break; + case SerializerNodeUnknown: + case SerializerNodeValue: + case SerializerNodeObjectProperty: + case SerializerNodeArrayItem: + default:; } if (HasChildren()) { @@ -341,6 +347,11 @@ class SerializerNode { case SerializerNodeArray: repr += ident + "]"; break; + case SerializerNodeUnknown: + case SerializerNodeValue: + case SerializerNodeObjectProperty: + case SerializerNodeArrayItem: + default:; } if (!IsLast()) repr += ","; diff --git a/Std.h b/Std.h index a80ec9fe6..cd268432c 100644 --- a/Std.h +++ b/Std.h @@ -23,6 +23,7 @@ #ifndef __MQL__ // Allows the preprocessor to include a header file when it is needed. #pragma once +#include "Math.define.h" #endif // Data types. @@ -155,7 +156,7 @@ class _cpp_array { /** * Returns number of elements in the array. */ - int size() const { return m_data.size(); } + int size() const { return (int)m_data.size(); } /** * Checks whether @@ -231,6 +232,12 @@ bool IsNull(const string& str) { return str == ""; } #define SYMBOL_MARGIN_STOPLIMIT ((ENUM_SYMBOL_INFO_DOUBLE)48) #endif +template +class InvalidEnumValue { + public: + static T value() { return (T)INT_MAX; } +}; + #ifndef __MQL__ // Converter of NULL_VALUE into expected type. e.g., "int x = NULL_VALUE" will end up with "x = 0". struct _NULL_VALUE { diff --git a/String.mqh b/String.mqh index f8a4d18f6..ab240c4db 100644 --- a/String.mqh +++ b/String.mqh @@ -25,6 +25,7 @@ #define STRING_MQH // Includes. +#include "Array.extern.h" #include "Std.h" #include "String.extern.h" diff --git a/Trade/tests/TradeSignal.test.cpp b/Trade/tests/TradeSignal.test.cpp index b230c5123..906fe43c2 100644 --- a/Trade/tests/TradeSignal.test.cpp +++ b/Trade/tests/TradeSignal.test.cpp @@ -25,8 +25,8 @@ */ // Includes. -#include "../../Std.h" #include "../../Common.define.h" #include "../../Common.extern.h" -//#include "../../String.extern.h" +#include "../../Std.h" +#include "../../String.extern.h" #include "../TradeSignal.h" diff --git a/tests/BufferStructTest.mq5 b/tests/BufferStructTest.mq5 index a55ed6baa..f5881fb70 100644 --- a/tests/BufferStructTest.mq5 +++ b/tests/BufferStructTest.mq5 @@ -28,6 +28,7 @@ #include "../BufferStruct.mqh" #include "../Data.define.h" #include "../Data.struct.h" +#include "../SerializerConverter.mqh" #include "../SerializerJSON.mqh" #include "../Std.h" #include "../Test.mqh" diff --git a/tests/SerializerTest.mq5 b/tests/SerializerTest.mq5 index 5f10e70e5..fb619c193 100644 --- a/tests/SerializerTest.mq5 +++ b/tests/SerializerTest.mq5 @@ -246,7 +246,7 @@ int OnInit() { SerializerConverter::FromObject(configs1).ToFile("configs.json"); - SerializerConverter stub3(Serializer::MakeStubObject>(0, 1, configs1[0].Size())); + SerializerConverter stub3(SerializerConverter::MakeStubObject>(0, 1, configs1[0].Size())); SerializerConverter::FromObject(configs1).ToFile("configs.csv", SERIALIZER_CSV_INCLUDE_TITLES, &stub3); string configs1_json = SerializerConverter::FromObject(configs1).ToString(); @@ -284,7 +284,7 @@ int OnInit() { string configs2_imported = SerializerConverter::FromObject(configs2).ToString(); Print("configs2 imported: ", configs2_imported); - SerializerConverter stub4(Serializer::MakeStubObject>(0, 1, 6)); + SerializerConverter stub4(SerializerConverter::MakeStubObject>(0, 1, 6)); SerializerConverter::FromObject(entries_map) .ToFile("configs_key.csv", SERIALIZER_CSV_INCLUDE_TITLES_TREE | SERIALIZER_CSV_INCLUDE_KEY, &stub4); From 8d1e4a5e7c312f720f0c5d65911902d81b49488f Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Mon, 24 Jan 2022 16:32:36 +0100 Subject: [PATCH 73/81] Should fix all GCC warnings. --- Dict.mqh | 1 + DictBase.mqh | 2 +- DictObject.mqh | 1 + DictSlot.mqh | 2 +- DictSlotsRef.h | 2 +- DictStruct.mqh | 1 + Math.define.h | 2 +- Object.mqh | 9 ++++----- Serializer.mqh | 1 - Trade/TradeSignal.struct.h | 8 ++++---- Trade/TradeSignalManager.struct.h | 2 +- Trade/tests/TradeSignal.test.cpp | 2 ++ Trade/tests/TradeSignalManager.test.cpp | 4 +++- 13 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Dict.mqh b/Dict.mqh index c5275b985..1d2aa7fb2 100644 --- a/Dict.mqh +++ b/Dict.mqh @@ -28,6 +28,7 @@ #include "DictBase.mqh" #include "Matrix.mqh" #include "Serializer.mqh" +#include "SerializerNodeIterator.mqh" template class DictIterator : public DictIteratorBase { diff --git a/DictBase.mqh b/DictBase.mqh index 62a2a1432..2bfe12d96 100644 --- a/DictBase.mqh +++ b/DictBase.mqh @@ -241,7 +241,7 @@ class DictBase { */ void FillHoleUnsorted(int _hole_slot_idx) { // After moving last element to fill the hole we - if (_hole_slot_idx == Size() - 1) { + if ((unsigned int)_hole_slot_idx == Size() - 1) { // We've just removed last element, thus don't need to do anything. } else { // Moving last slot into given one. diff --git a/DictObject.mqh b/DictObject.mqh index 36027b8ed..e45857e76 100644 --- a/DictObject.mqh +++ b/DictObject.mqh @@ -27,6 +27,7 @@ #include "Convert.mqh" #include "DictBase.mqh" #include "Serializer.mqh" +#include "SerializerNodeIterator.mqh" template class DictObjectIterator : public DictIteratorBase { diff --git a/DictSlot.mqh b/DictSlot.mqh index c64aa3eda..3c1fe29e1 100644 --- a/DictSlot.mqh +++ b/DictSlot.mqh @@ -52,7 +52,7 @@ class DictSlot { void AddFlags(unsigned char flags) { _flags |= flags; } - void RemoveFlags(unsigned char flags) { _flags &= ~flags; } + void RemoveFlags(unsigned char flags) { _flags &= (unsigned char)~flags; } }; #endif diff --git a/DictSlotsRef.h b/DictSlotsRef.h index ccf9e0b26..e5ae9ee58 100644 --- a/DictSlotsRef.h +++ b/DictSlotsRef.h @@ -61,7 +61,7 @@ struct DictSlotsRef { */ void AddConflicts(int num) { if (num != 0) { - _avg_conflicts += float(num) / ++_num_conflicts; + _avg_conflicts += (float)num / (float)++_num_conflicts; } } diff --git a/DictStruct.mqh b/DictStruct.mqh index f9d33c15d..5bff53459 100644 --- a/DictStruct.mqh +++ b/DictStruct.mqh @@ -31,6 +31,7 @@ class Log; #include "DictBase.mqh" #include "DictIteratorBase.mqh" #include "Serializer.mqh" +#include "SerializerNodeIterator.mqh" // DictIterator could be used as DictStruct iterator. #define DictStructIterator DictIteratorBase diff --git a/Math.define.h b/Math.define.h index 8402d7a5e..8e519a71f 100644 --- a/Math.define.h +++ b/Math.define.h @@ -57,4 +57,4 @@ #define DBL_MIN std::numeric_limits::min() #define DBL_MAX std::numeric_limits::max() -#endif \ No newline at end of file +#endif diff --git a/Object.mqh b/Object.mqh index ecbfcece3..d0dd1fadb 100644 --- a/Object.mqh +++ b/Object.mqh @@ -43,7 +43,7 @@ class Object : public Dynamic { /** * Class constructor. */ - Object() : id(rand()), obj(THIS_PTR) {} + Object() : obj(THIS_PTR), id(rand()) {} Object(void *_obj, long _id = __LINE__) { obj = _obj; id = _id; @@ -110,11 +110,11 @@ class Object : public Dynamic { /** * Safely delete the object. */ -#ifdef __cplusplus template static void Delete(T *_obj) { -#else - static void Delete(void *_obj) { +#ifdef __cplusplus + static_assert(!std::is_same::value, + "Please avoid deleting void* pointers as no destructor will be called!"); #endif #ifdef __MQL__ if (CheckPointer(_obj) == POINTER_DYNAMIC) { @@ -124,7 +124,6 @@ class Object : public Dynamic { delete _obj; } } - void Delete() { Delete(obj); } /* Virtual methods */ diff --git a/Serializer.mqh b/Serializer.mqh index 533aff32c..cdd52b761 100644 --- a/Serializer.mqh +++ b/Serializer.mqh @@ -29,7 +29,6 @@ #include "Serializer.define.h" #include "Serializer.enum.h" #include "SerializerNode.mqh" -#include "SerializerNodeIterator.mqh" #include "SerializerNodeParam.mqh" #define SERIALIZER_DEFAULT_FP_PRECISION 8 diff --git a/Trade/TradeSignal.struct.h b/Trade/TradeSignal.struct.h index a55206c84..fb7042fb0 100644 --- a/Trade/TradeSignal.struct.h +++ b/Trade/TradeSignal.struct.h @@ -53,12 +53,12 @@ // Structure for a trade signal. struct TradeSignalEntry { protected: - ENUM_TIMEFRAMES tf; // Timeframe. - float strength; // Signal strength. - float weight; // Signal weight. long magic_id; // Magic identifier. - long timestamp; // Creation timestamp unsigned int signals; // Store signals (@see: ENUM_TRADE_SIGNAL_FLAG). + float strength; // Signal strength. + ENUM_TIMEFRAMES tf; // Timeframe. + long timestamp; // Creation timestamp + float weight; // Signal weight. public: /* Struct's enumerations */ diff --git a/Trade/TradeSignalManager.struct.h b/Trade/TradeSignalManager.struct.h index 3fd69fa17..d4be49393 100644 --- a/Trade/TradeSignalManager.struct.h +++ b/Trade/TradeSignalManager.struct.h @@ -34,8 +34,8 @@ */ struct TradeSignalManagerParams { protected: - long last_check; // Last check. short freq; // Signal process refresh frequency (in sec). + long last_check; // Last check. public: /* Struct's enumerations */ diff --git a/Trade/tests/TradeSignal.test.cpp b/Trade/tests/TradeSignal.test.cpp index 906fe43c2..696ec4422 100644 --- a/Trade/tests/TradeSignal.test.cpp +++ b/Trade/tests/TradeSignal.test.cpp @@ -30,3 +30,5 @@ #include "../../Std.h" #include "../../String.extern.h" #include "../TradeSignal.h" + +int main(int argc, char **argv) {} diff --git a/Trade/tests/TradeSignalManager.test.cpp b/Trade/tests/TradeSignalManager.test.cpp index 9017a08f8..7ca976d9f 100644 --- a/Trade/tests/TradeSignalManager.test.cpp +++ b/Trade/tests/TradeSignalManager.test.cpp @@ -25,8 +25,10 @@ */ // Includes. -#include "../../Std.h" #include "../../Common.define.h" #include "../../Common.extern.h" +#include "../../Std.h" #include "../../String.extern.h" #include "../TradeSignalManager.h" + +int main(int argc, char **argv) {} From afb673c4d50da509f9ca2572425fc4a8e1642226 Mon Sep 17 00:00:00 2001 From: Adrian Kierzkowski Date: Wed, 26 Jan 2022 13:26:22 +0100 Subject: [PATCH 74/81] Should fix new issues with C++ compatibility. --- DictObject.mqh | 6 +++--- SerializerConverter.mqh | 2 +- Tick.struct.h | 40 ++++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/DictObject.mqh b/DictObject.mqh index 1eb2c8abe..fbfd681aa 100644 --- a/DictObject.mqh +++ b/DictObject.mqh @@ -220,18 +220,18 @@ class DictObject : public DictBase { unsigned int position; DictSlot* keySlot = this PTR_DEREF GetSlotByKey(dictSlotsRef, key, position); - if (keySlot == NULL && !IsGrowUpAllowed()) { + if (keySlot == NULL && !this PTR_DEREF IsGrowUpAllowed()) { // Resize is prohibited. return false; } // Will resize dict if there were performance problems before. - if (allow_resize && IsGrowUpAllowed() && !dictSlotsRef.IsPerformant()) { + if (allow_resize && this PTR_DEREF IsGrowUpAllowed() && !dictSlotsRef.IsPerformant()) { if (!GrowUp()) { return false; } // We now have new positions of slots, so we have to take the corrent slot again. - keySlot = GetSlotByKey(dictSlotsRef, key, position); + keySlot = this PTR_DEREF GetSlotByKey(dictSlotsRef, key, position); } if (keySlot == NULL && dictSlotsRef._num_used == ArraySize(dictSlotsRef.DictSlots)) { diff --git a/SerializerConverter.mqh b/SerializerConverter.mqh index 060326f78..dbed96988 100644 --- a/SerializerConverter.mqh +++ b/SerializerConverter.mqh @@ -54,7 +54,7 @@ class SerializerConverter { return ""; } - return root_node.ToString(_json_flags); + return root_node PTR_DEREF ToString(_json_flags); } template diff --git a/Tick.struct.h b/Tick.struct.h index 71c4220ba..dbb226a4f 100644 --- a/Tick.struct.h +++ b/Tick.struct.h @@ -32,6 +32,24 @@ // Includes. #include "DateTime.extern.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 + /** * Structure for storing ask and bid prices of the symbol. */ @@ -51,24 +69,6 @@ template struct TickTAB : TickAB { datetime time; // Time of the last prices update. // Struct constructors. - TickTAB(datetime _time = 0, T _ask = 0, T _bid = 0) : time(_time), TickAB(_ask, _bid) {} - TickTAB(MqlTick &_tick) : time(_tick.time), TickAB(_tick) {} + TickTAB(datetime _time = 0, T _ask = 0, T _bid = 0) : time(_time), TickAB(_ask, _bid) {} + TickTAB(MqlTick &_tick) : time(_tick.time), TickAB(_tick) {} }; - -#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 From e61fe6c09d12df66ddc16a4490e4e32591b6ae29 Mon Sep 17 00:00:00 2001 From: kenorb Date: Thu, 24 Mar 2022 23:47:28 +0000 Subject: [PATCH 75/81] CPP: Removes EnumToString --- Serializer.mqh | 4 +++- SerializerNode.mqh | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Serializer.mqh b/Serializer.mqh index 50b3d4017..e761be724 100644 --- a/Serializer.mqh +++ b/Serializer.mqh @@ -30,6 +30,7 @@ #include "Serializer.enum.h" #include "SerializerNode.mqh" #include "SerializerNodeParam.mqh" +#include "Terminal.define.h" #define SERIALIZER_DEFAULT_FP_PRECISION 8 @@ -431,7 +432,8 @@ class Serializer { Convert::StringToType(PTR_ATTRIB(PTR_ATTRIB(child, GetValueParam()), _string), value); break; default: - Print("Error: Wrong param type ", EnumToString(paramType), "!"); + Print("Error: Wrong param type!"); + SetUserError(ERR_INVALID_PARAMETER); DebugBreak(); } diff --git a/SerializerNode.mqh b/SerializerNode.mqh index 1b3979ce0..27fbd2307 100644 --- a/SerializerNode.mqh +++ b/SerializerNode.mqh @@ -28,6 +28,7 @@ #include "Math.extern.h" #include "SerializerNode.enum.h" #include "SerializerNodeParam.mqh" +#include "Terminal.define.h" class SerializerNode { protected: @@ -138,7 +139,8 @@ class SerializerNode { _result += StringLen(PTR_ATTRIB(_value, _string)) + 1; break; default: - Print("Error: Wrong value type ", EnumToString(GetType()), "!"); + Print("Error: Wrong value type!"); + SetUserError(ERR_INVALID_PARAMETER); DebugBreak(); } } From 66f434249879fbb0a457b504697e4cb5a2ffd499 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 29 May 2022 21:17:15 +0100 Subject: [PATCH 76/81] Refactors IndicatorData class to be inherited by Indicator class --- EA.mqh | 2 +- Indicator.mqh | 117 +-- Indicator.struct.h | 359 +-------- Indicator.struct.serialize.h | 66 -- Indicator/IndicatorTickOrCandleSource.h | 6 +- Indicator/IndicatorTickSource.h | 6 +- Indicator/tests/IndicatorTf.test.mq5 | 2 +- Indicator/tests/classes/IndicatorTickDummy.h | 2 +- Indicator/tests/classes/IndicatorTickReal.h | 8 +- Indicator/tests/classes/Indicators.h | 10 +- IndicatorBase.h | 517 +------------ IndicatorData.mqh | 716 +++++++++++++----- IndicatorData.struct.h | 385 ++++++++++ IndicatorData.struct.serialize.h | 97 +++ ....signal.h => IndicatorData.struct.signal.h | 0 Indicators/Bitwise/Indi_Candle.mqh | 2 +- Indicators/Bitwise/Indi_Pattern.mqh | 2 +- Indicators/Indi_AC.mqh | 4 +- Indicators/Indi_AD.mqh | 4 +- Indicators/Indi_ADX.mqh | 4 +- Indicators/Indi_ADXW.mqh | 8 +- Indicators/Indi_AMA.mqh | 10 +- Indicators/Indi_AO.mqh | 4 +- Indicators/Indi_ASI.mqh | 8 +- Indicators/Indi_ATR.mqh | 4 +- Indicators/Indi_Alligator.mqh | 4 +- Indicators/Indi_AppliedPrice.mqh | 4 +- Indicators/Indi_BWMFI.mqh | 4 +- Indicators/Indi_BWZT.mqh | 16 +- Indicators/Indi_Bands.mqh | 10 +- Indicators/Indi_BearsPower.mqh | 4 +- Indicators/Indi_BullsPower.mqh | 4 +- Indicators/Indi_CCI.mqh | 6 +- Indicators/Indi_CHO.mqh | 8 +- Indicators/Indi_CHV.mqh | 8 +- Indicators/Indi_ColorBars.mqh | 8 +- Indicators/Indi_ColorCandlesDaily.mqh | 8 +- Indicators/Indi_ColorLine.mqh | 16 +- Indicators/Indi_CustomMovingAverage.mqh | 2 +- Indicators/Indi_DEMA.mqh | 10 +- Indicators/Indi_DeMarker.mqh | 4 +- Indicators/Indi_Demo.mqh | 4 +- Indicators/Indi_DetrendedPrice.mqh | 8 +- Indicators/Indi_Drawer.mqh | 9 +- Indicators/Indi_Envelopes.mqh | 6 +- Indicators/Indi_Force.mqh | 4 +- Indicators/Indi_FractalAdaptiveMA.mqh | 8 +- Indicators/Indi_Fractals.mqh | 4 +- Indicators/Indi_Gator.mqh | 4 +- Indicators/Indi_HeikenAshi.mqh | 8 +- Indicators/Indi_Ichimoku.mqh | 4 +- Indicators/Indi_Killzones.mqh | 2 +- Indicators/Indi_MA.mqh | 6 +- Indicators/Indi_MACD.mqh | 4 +- Indicators/Indi_MFI.mqh | 4 +- Indicators/Indi_MassIndex.mqh | 8 +- Indicators/Indi_Momentum.mqh | 6 +- Indicators/Indi_OBV.mqh | 4 +- Indicators/Indi_OsMA.mqh | 4 +- Indicators/Indi_Pivot.mqh | 2 +- Indicators/Indi_PriceChannel.mqh | 8 +- Indicators/Indi_PriceFeeder.mqh | 2 +- Indicators/Indi_PriceVolumeTrend.mqh | 8 +- Indicators/Indi_RS.mqh | 2 +- Indicators/Indi_RSI.mqh | 12 +- Indicators/Indi_RVI.mqh | 4 +- Indicators/Indi_RateOfChange.mqh | 8 +- Indicators/Indi_SAR.mqh | 4 +- Indicators/Indi_StdDev.mqh | 6 +- Indicators/Indi_Stochastic.mqh | 4 +- Indicators/Indi_TEMA.mqh | 6 +- Indicators/Indi_TRIX.mqh | 8 +- Indicators/Indi_UltimateOscillator.mqh | 26 +- Indicators/Indi_VIDYA.mqh | 8 +- Indicators/Indi_VROC.mqh | 8 +- Indicators/Indi_Volumes.mqh | 8 +- Indicators/Indi_WPR.mqh | 4 +- Indicators/Indi_WilliamsAD.mqh | 8 +- Indicators/Indi_ZigZag.mqh | 8 +- Indicators/Indi_ZigZagColor.mqh | 8 +- Indicators/OHLC/Indi_OHLC.mqh | 2 +- Indicators/Price/Indi_Price.mqh | 2 +- Indicators/Special/Indi_Custom.mqh | 2 +- Indicators/Special/Indi_Math.mqh | 6 +- Indicators/Tick/Indi_TickMt.mqh | 2 +- Storage/ValueStorage.indicator.h | 6 +- tests/CompileTest.mq5 | 1 + tests/DrawIndicatorTest.mq5 | 12 +- tests/IndicatorBaseTest.mq4 | 28 + tests/IndicatorBaseTest.mq5 | 37 + tests/IndicatorDataTest.mq4 | 184 +---- tests/IndicatorDataTest.mq5 | 37 + tests/IndicatorsTest.mq5 | 63 +- 93 files changed, 1402 insertions(+), 1688 deletions(-) create mode 100644 IndicatorData.struct.h create mode 100644 IndicatorData.struct.serialize.h rename Indicator.struct.signal.h => IndicatorData.struct.signal.h (100%) create mode 100644 tests/IndicatorBaseTest.mq4 create mode 100644 tests/IndicatorBaseTest.mq5 create mode 100644 tests/IndicatorDataTest.mq5 diff --git a/EA.mqh b/EA.mqh index 4c1d71688..8fba5ff06 100644 --- a/EA.mqh +++ b/EA.mqh @@ -426,7 +426,7 @@ class EA { if (eparams.CheckFlagDataStore(EA_DATA_STORE_INDICATOR)) { for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { Strategy *_strati = iter.Value().Ptr(); - IndicatorBase *_indi = _strati.GetIndicator(); + IndicatorData *_indi = _strati.GetIndicator(); if (_indi != NULL) { ENUM_TIMEFRAMES _itf = _indi.GetParams().tf.GetTf(); IndicatorDataEntry _ientry = _indi.GetEntry(); diff --git a/Indicator.mqh b/Indicator.mqh index 58f6d3744..c2b58899f 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -38,8 +38,7 @@ class Chart; #include "Indicator.struct.cache.h" #include "Indicator.struct.h" #include "Indicator.struct.serialize.h" -#include "Indicator.struct.signal.h" -#include "IndicatorBase.h" +#include "IndicatorData.mqh" #include "Math.h" #include "Object.mqh" #include "Refs.mqh" @@ -80,10 +79,9 @@ double iCustom5(string _symbol, ENUM_TIMEFRAMES _tf, string _name, A _a, B _b, C * Class to deal with indicators. */ template -class Indicator : public IndicatorBase { +class Indicator : public IndicatorData { protected: DrawIndicator* draw; - BufferStruct idata; TS iparams; protected: @@ -144,8 +142,8 @@ class Indicator : public IndicatorBase { /** * Class constructor. */ - Indicator(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) - : IndicatorBase(_iparams.GetTf(), NULL) { + Indicator(const TS& _iparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) + : IndicatorData(_iparams.GetTf(), NULL) { iparams = _iparams; if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); @@ -153,12 +151,12 @@ class Indicator : public IndicatorBase { } Init(); } - Indicator(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorBase(_tf) { + Indicator(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorData(_tf) { iparams = _iparams; Init(); } Indicator(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") - : IndicatorBase(_tf) { + : IndicatorData(_tf) { iparams.SetIndicatorType(_itype); iparams.SetShift(_shift); Init(); @@ -268,48 +266,6 @@ class Indicator : public IndicatorBase { return GetIndicatorBuffers() > 0 && GetIndicatorBuffers() <= 512; } - /** - * Gets indicator data from a buffer and copy into struct array. - * - * @return - * Returns true of successful copy. - * Returns false on invalid values. - */ - bool CopyEntries(IndicatorDataEntry& _data[], int _count, int _start_shift = 0) { - bool _is_valid = true; - if (ArraySize(_data) < _count) { - _is_valid &= ArrayResize(_data, _count) > 0; - } - for (int i = 0; i < _count; i++) { - IndicatorDataEntry _entry = GetEntry(_start_shift + i); - _is_valid &= _entry.IsValid(); - _data[i] = _entry; - } - return _is_valid; - } - - /** - * Gets indicator data from a buffer and copy into array of values. - * - * @return - * Returns true of successful copy. - * Returns false on invalid values. - */ - template - bool CopyValues(T& _data[], int _count, int _start_shift = 0, int _mode = 0) { - bool _is_valid = true; - if (ArraySize(_data) < _count) { - _count = ArrayResize(_data, _count); - _count = _count > 0 ? _count : ArraySize(_data); - } - for (int i = 0; i < _count; i++) { - IndicatorDataEntry _entry = GetEntry(_start_shift + i); - _is_valid &= _entry.IsValid(); - _data[i] = (T)_entry[_mode]; - } - return _is_valid; - } - /** * CopyBuffer() method to be used on Indicator instance with ValueStorage buffer. * @@ -340,52 +296,6 @@ class Indicator : public IndicatorBase { } */ - /** - * Validates currently selected indicator used as data source. - */ - void ValidateSelectedDataSource() { - if (HasDataSource()) { - ValidateDataSource(THIS_PTR, GetDataSourceRaw()); - } - } - - /** - * Loads and validates built-in indicators whose can be used as data source. - */ - void ValidateDataSource(IndicatorBase* _target, IndicatorBase* _source) { - if (_target == NULL) { - Alert("Internal Error! _target is NULL in ", __FUNCTION_LINE__, "."); - DebugBreak(); - return; - } - - if (_source == NULL) { - Alert("Error! You have to select source indicator's via SetDataSource()."); - DebugBreak(); - return; - } - - if (!_target.IsDataSourceModeSelectable()) { - // We don't validate source mode as it will use all modes. - return; - } - - if (_source.GetModeCount() > 1 && _target.GetDataSourceMode() == -1) { - // Mode must be selected if source indicator has more that one mode. - Alert("Warning! ", GetName(), - " must select source indicator's mode via SetDataSourceMode(int). Defaulting to mode 0."); - _target.SetDataSourceMode(0); - DebugBreak(); - } else if (_source.GetModeCount() == 1 && _target.GetDataSourceMode() == -1) { - _target.SetDataSourceMode(0); - } else if (_target.GetDataSourceMode() < 0 || _target.GetDataSourceMode() > _source.GetModeCount()) { - Alert("Error! ", _target.GetName(), - " must select valid source indicator's mode via SetDataSourceMode(int) between 0 and ", - _source.GetModeCount(), "."); - DebugBreak(); - } - } - /** * Checks whether indicator have given mode index. * @@ -535,11 +445,6 @@ class Indicator : public IndicatorBase { /* Getters */ - /** - * Get pointer to data of indicator. - */ - BufferStruct* GetData() { return GetPointer(idata); } - /** * Returns the highest bar's index (shift). */ @@ -696,8 +601,8 @@ class Indicator : public IndicatorBase { /** * Returns currently selected data source doing validation. */ - IndicatorBase* GetDataSource() { - IndicatorBase* _result = NULL; + IndicatorData* GetDataSource() { + IndicatorData* _result = NULL; if (GetDataSourceRaw() != NULL) { _result = GetDataSourceRaw(); @@ -707,7 +612,7 @@ class Indicator : public IndicatorBase { if (indicators.KeyExists(_source_id)) { _result = indicators[_source_id].Ptr(); } else { - Ref _source = FetchDataSource((ENUM_INDICATOR_TYPE)_source_id); + Ref _source = FetchDataSource((ENUM_INDICATOR_TYPE)_source_id); if (!_source.IsSet()) { Alert(GetName(), " has no built-in source indicator ", _source_id); @@ -722,7 +627,7 @@ class Indicator : public IndicatorBase { // User sets data source's mode to On-Indicator, but not set data source via SetDataSource()! // Requesting potential data source. - IndicatorBase* _ds = OnDataSourceRequest(); + IndicatorData* _ds = OnDataSourceRequest(); if (_ds != NULL) { // Initializing with new data source. @@ -980,7 +885,7 @@ class Indicator : public IndicatorBase { /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { + void SetDataSource(IndicatorData* _indi, int _input_mode = -1) override { if (indi_src.IsSet()) { if (bool(flags | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT) && !bool(_indi.GetFlags() | INDI_FLAG_INDEXABLE_BY_SHIFT)) { diff --git a/Indicator.struct.h b/Indicator.struct.h index d9ecc205a..034141b5d 100644 --- a/Indicator.struct.h +++ b/Indicator.struct.h @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ @@ -45,362 +45,6 @@ struct ChartParams; #include "SerializerNode.enum.h" #include "Storage/ValueStorage.indicator.h" -// Type-less value for IndicatorDataEntryValue structure. -union IndicatorDataEntryTypelessValue { - double vdbl; - float vflt; - int vint; - long vlong; -}; - -// Type-aware value for IndicatorDataEntry class. -struct IndicatorDataEntryValue { - unsigned char flags; - IndicatorDataEntryTypelessValue value; - - // Returns type of the value. - ENUM_DATATYPE GetDataType() { return (ENUM_DATATYPE)((flags & 0xF0) >> 4); } - - // Sets type of the value. - void SetDataType(ENUM_DATATYPE _type) { - // Clearing type. - flags &= 0x0F; - - // Setting type. - flags |= (unsigned char)_type << 4; - } - - // Union operators. - template - T operator*(const T _value) { - return Get() * _value; - } - template - T operator+(const T _value) { - return Get() + _value; - } - template - T operator-(const T _value) { - return Get() - _value; - } - template - T operator/(const T _value) { - return Get() / _value; - } - template - bool operator!=(const T _value) { - return Get() != _value; - } - template - bool operator<(const T _value) { - return Get() < _value; - } - template - bool operator<=(const T _value) { - return Get() <= _value; - } - template - bool operator==(const T _value) { - return Get() == _value; - } - template - bool operator>(const T _value) { - return Get() > _value; - } - template - bool operator>=(const T _value) { - return Get() >= _value; - } - template - void operator=(const T _value) { - Set(_value); - } - // Checkers. - template - bool IsGt(T _value) { - return Get() > _value; - } - template - bool IsLt(T _value) { - return Get() < _value; - } - // Getters. - double GetDbl() { return value.vdbl; } - float GetFloat() { return value.vflt; } - int GetInt() { return value.vint; } - long GetLong() { return value.vlong; } - template - void Get(T &_out) { - _out = Get(); - } - template - T Get() { - T _v; - Get(_v); - return _v; - } - void Get(double &_out) { _out = value.vdbl; } - void Get(float &_out) { _out = value.vflt; } - void Get(int &_out) { _out = value.vint; } - void Get(unsigned int &_out) { _out = (unsigned int)value.vint; } - void Get(long &_out) { _out = value.vlong; } - void Get(unsigned long &_out) { _out = (unsigned long)value.vint; } - // Setters. - template - void Set(T _value) { - Set(_value); - } - void Set(double _value) { - value.vdbl = _value; - SetDataType(TYPE_DOUBLE); - } - void Set(float _value) { - value.vflt = _value; - SetDataType(TYPE_FLOAT); - } - void Set(int _value) { - value.vint = _value; - SetDataType(TYPE_INT); - } - void Set(unsigned int _value) { - value.vint = (int)_value; - SetDataType(TYPE_UINT); - } - void Set(long _value) { - value.vlong = _value; - SetDataType(TYPE_LONG); - } - void Set(unsigned long _value) { - value.vlong = (long)_value; - SetDataType(TYPE_ULONG); - } - // Serializers. - // SERIALIZER_EMPTY_STUB - SerializerNodeType Serialize(Serializer &_s); - // To string - template - string ToString() { - return (string)Get(); - } -}; - -/* Structure for indicator data entry. */ -struct IndicatorDataEntry { - long timestamp; // Timestamp of the entry's bar. - unsigned short flags; // Indicator entry flags. - ARRAY(IndicatorDataEntryValue, values); - - // Constructors. - IndicatorDataEntry(int _size = 1) : flags(INDI_ENTRY_FLAG_NONE), timestamp(0) { Resize(_size); } - IndicatorDataEntry(IndicatorDataEntry &_entry) { THIS_REF = _entry; } - int GetSize() { return ArraySize(values); } - // Operator overloading methods. - template - T operator*(const T _value) { - return values[0].Get() * _value; - } - template - T operator+(const T _value) { - return values[0].Get() + _value; - } - template - T operator-(const T _value) { - return values[0].Get() - _value; - } - template - T operator/(const T _value) { - return values[0].Get() / _value; - } - template - T operator[](I _index) { - return values[(int)_index].Get(); - } - template <> - double operator[](int _index) { - if (_index >= ArraySize(values)) { - return 0; - } - double _value; - values[_index].Get(_value); - return _value; - } - // Checkers. - template - bool HasValue(T _value) { - bool _result = false; - int _asize = ArraySize(values); - T _value2; - for (int i = 0; i < _asize; i++) { - values[i].Get(_value2); - if (_value == _value2) { - _result = true; - break; - } - } - return _result; - } - template - bool IsGe(T _value) { - return GetMin() >= _value; - } - template - bool IsGt(T _value) { - return GetMin() > _value; - } - template - bool IsLe(T _value) { - return GetMax() <= _value; - } - template - bool IsLt(T _value) { - return GetMax() < _value; - } - template - bool IsWithinRange(T _min, T _max) { - return GetMin() >= _min && GetMax() <= _max; - } - // Getters. - template - void GetArray(ARRAY_REF(T, _out), int _size = 0) { - int _asize = _size > 0 ? _size : ArraySize(_out); - for (int i = 0; i < _asize; i++) { - values[i].Get(_out[i]); - } - }; - template - T GetAvg(int _size = 0) { - int _asize = _size > 0 ? _size : ArraySize(values); - T _avg = GetSum() / _asize; - return _avg; - }; - template - T GetMin(int _size = 0) { - int _asize = _size > 0 ? _size : ArraySize(values); - int _index = 0; - for (int i = 1; i < _asize; i++) { - _index = values[i].Get() < values[_index].Get() ? i : _index; - } - return values[_index].Get(); - }; - template - T GetMax(int _size = 0) { - int _asize = _size > 0 ? _size : ArraySize(values); - int _index = 0; - for (int i = 1; i < _asize; i++) { - _index = values[i].Get() > values[_index].Get() ? i : _index; - } - return values[_index].Get(); - }; - template - T GetSum(int _size = 0) { - int _asize = _size > 0 ? _size : ArraySize(values); - T _sum = 0; - for (int i = 1; i < _asize; i++) { - _sum = +values[i].Get(); - } - return _sum; - }; - template - T GetValue(int _index = 0) { - return values[_index].Get(); - }; - template - void GetValues(T &_out1, T &_out2) { - values[0].Get(_out1); - values[1].Get(_out2); - }; - template - void GetValues(T &_out1, T &_out2, T &_out3) { - values[0].Get(_out1); - values[1].Get(_out2); - values[2].Get(_out3); - }; - template - void GetValues(T &_out1, T &_out2, T &_out3, T &_out4) { - values[0].Get(_out1); - values[1].Get(_out2); - values[2].Get(_out3); - values[3].Get(_out4); - }; - - // Getters. - int GetDayOfYear() { return DateTimeStatic::DayOfYear(timestamp); } - int GetMonth() { return DateTimeStatic::Month(timestamp); } - int GetYear() { return DateTimeStatic::Year(timestamp); } - long GetTime() { return timestamp; }; - ENUM_DATATYPE GetDataType(int _mode) { return values[_mode].GetDataType(); } - ushort GetDataTypeFlags(ENUM_DATATYPE _dt) { - switch (_dt) { - case TYPE_BOOL: - case TYPE_CHAR: - SetUserError(ERR_INVALID_PARAMETER); - break; - case TYPE_INT: - return INDI_ENTRY_FLAG_NONE; - case TYPE_LONG: - return INDI_ENTRY_FLAG_IS_DOUBLED; - case TYPE_UINT: - return INDI_ENTRY_FLAG_IS_UNSIGNED; - case TYPE_ULONG: - return INDI_ENTRY_FLAG_IS_UNSIGNED | INDI_ENTRY_FLAG_IS_DOUBLED; - case TYPE_DOUBLE: - return INDI_ENTRY_FLAG_IS_REAL | INDI_ENTRY_FLAG_IS_DOUBLED; - case TYPE_FLOAT: - return INDI_ENTRY_FLAG_IS_REAL; - case TYPE_STRING: - case TYPE_UCHAR: - SetUserError(ERR_INVALID_PARAMETER); - break; - default: - SetUserError(ERR_INVALID_PARAMETER); - break; - } - SetUserError(ERR_INVALID_PARAMETER); - return INDI_ENTRY_FLAG_NONE; - } - // Setters. - bool Resize(int _size = 0) { return _size > 0 ? ArrayResize(values, _size) > 0 : true; } - // Value flag methods for bitwise operations. - bool CheckFlag(INDICATOR_ENTRY_FLAGS _prop) { return CheckFlags(_prop); } - bool CheckFlags(unsigned short _flags) { return (flags & _flags) != 0; } - bool CheckFlagsAll(unsigned short _flags) { return (flags & _flags) == _flags; } - void AddFlags(unsigned short _flags) { flags |= _flags; } - void RemoveFlags(unsigned short _flags) { flags &= ~_flags; } - void SetFlag(INDICATOR_ENTRY_FLAGS _flag, bool _value) { - if (_value) { - AddFlags(_flag); - } else { - RemoveFlags(_flag); - } - } - void SetFlags(unsigned short _flags) { flags = _flags; } - unsigned short GetFlags() { return flags; } - // Converters. - // State checkers. - bool IsValid() { return CheckFlags(INDI_ENTRY_FLAG_IS_VALID); } - // Serializers. - void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) { - ArrayResize(values, _n1); - for (int i = 0; i < _n1; ++i) { - values[i] = (int)1; - } - } - SerializerNodeType Serialize(Serializer &_s); - template - string ToCSV() { - int _asize = ArraySize(values); - string _result = ""; - for (int i = 0; i < _asize; i++) { - _result += StringFormat("%s%s", (string)values[i].Get(), i < _asize ? "," : ""); - } - return _result; - } - template - string ToString() { - return ToCSV(); - } -}; - /* Structure for indicator parameters. */ struct IndicatorParams { public: // @todo: Change it to protected. @@ -479,6 +123,7 @@ struct IndicatorParams { ENUM_DATATYPE GetDataValueType() const { return dtype; } ENUM_IDATA_SOURCE_TYPE GetDataSourceType() const { return idstype; } ENUM_IDATA_VALUE_RANGE GetIDataValueRange() const { return idvrange; } + ENUM_INDICATOR_TYPE GetIndicatorType() { return itype; } ENUM_TIMEFRAMES GetTf() const { return tf.GetTf(); } template T GetInputParam(int _index, T _default) const { diff --git a/Indicator.struct.serialize.h b/Indicator.struct.serialize.h index 98e262c60..ed0c89915 100644 --- a/Indicator.struct.serialize.h +++ b/Indicator.struct.serialize.h @@ -30,72 +30,6 @@ // Forward class declaration. class Serializer; -/* Method to serialize IndicatorDataEntry structure. */ -SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) { - int _asize = ArraySize(values); - _s.Pass(THIS_REF, "datetime", timestamp, SERIALIZER_FIELD_FLAG_DYNAMIC); - _s.Pass(THIS_REF, "flags", flags, SERIALIZER_FIELD_FLAG_DYNAMIC); - for (int i = 0; i < _asize; i++) { - // _s.Pass(THIS_REF, (string)i, values[i], SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); // Can - // this work? _s.Pass(THIS_REF, (string)i, GetEntry(i), SERIALIZER_FIELD_FLAG_DYNAMIC | - // SERIALIZER_FIELD_FLAG_FEATURE); // Can this work? - - switch (values[i].GetDataType()) { - case TYPE_DOUBLE: - _s.Pass(THIS_REF, (string)i, values[i].value.vdbl, - SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); - break; - case TYPE_FLOAT: - _s.Pass(THIS_REF, (string)i, values[i].value.vflt, - SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); - break; - case TYPE_INT: - case TYPE_UINT: - if (CheckFlags(INDI_ENTRY_FLAG_IS_BITWISE)) { - // Split for each bit and pass 0 or 1. - for (int j = 0; j < sizeof(int) * 8; ++j) { - int _value = (values[i].value.vint & (1 << j)) != 0; - _s.Pass(THIS_REF, StringFormat("%d@%d", i, j), _value, SERIALIZER_FIELD_FLAG_FEATURE); - } - } else { - _s.Pass(THIS_REF, (string)i, values[i].value.vint, - SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); - } - break; - case TYPE_LONG: - case TYPE_ULONG: - if (CheckFlags(INDI_ENTRY_FLAG_IS_BITWISE)) { - // Split for each bit and pass 0 or 1. - /* @fixme: j, j already defined. - for (int j = 0; j < sizeof(int) * 8; ++j) { - int _value = (values[i].vlong & (1 << j)) != 0; - _s.Pass(THIS_REF, StringFormat("%d@%d", i, j), _value, SERIALIZER_FIELD_FLAG_FEATURE); - } - */ - SetUserError(ERR_INVALID_PARAMETER); - } else { - _s.Pass(THIS_REF, (string)i, values[i].value.vlong, - SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); - } - break; - default: - SetUserError(ERR_INVALID_PARAMETER); - break; - } - } - return SerializerNodeObject; -} - -/* Method to serialize IndicatorDataEntry's IndicatorDataEntryValue union. */ -SerializerNodeType IndicatorDataEntryValue::Serialize(Serializer &_s) { - _s.Pass(THIS_REF, "flags", flags); - _s.Pass(THIS_REF, "vdbl", value.vdbl); - _s.Pass(THIS_REF, "vflt", value.vflt); - _s.Pass(THIS_REF, "vint", value.vint); - _s.Pass(THIS_REF, "vlong", value.vlong); - return SerializerNodeObject; -}; - /* Method to serialize IndicatorParams structure. */ SerializerNodeType IndicatorParams::Serialize(Serializer &s) { s.Pass(THIS_REF, "name", name); diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h index 45fce1acd..961057c30 100644 --- a/Indicator/IndicatorTickOrCandleSource.h +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -57,7 +57,7 @@ class IndicatorTickOrCandleSource : public Indicator { * Called when user tries to set given data source. Could be used to check if indicator implements all required value * storages. */ - bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) override { + bool OnValidateDataSource(IndicatorData* _ds, string& _reason) override { // @todo Make use of this method. return true; } @@ -72,9 +72,9 @@ class IndicatorTickOrCandleSource : public Indicator { /** * Creates default, tick based indicator for given applied price. */ - IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) override { + IndicatorData* DataSourceRequestReturnDefault(int _applied_price) override { // Returning real candle indicator. Thus way we can use SetAppliedPrice() and select Ask or Bid price. - IndicatorBase* _indi; + IndicatorData* _indi; switch (_applied_price) { case PRICE_ASK: diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h index 6e1734f4c..ca59b4312 100644 --- a/Indicator/IndicatorTickSource.h +++ b/Indicator/IndicatorTickSource.h @@ -37,7 +37,7 @@ class IndicatorTickSource : public Indicator { /** * Class constructor. */ - IndicatorTickSource(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) + IndicatorTickSource(const TS& _iparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) : Indicator(_iparams, _indi_src, _indi_mode) {} IndicatorTickSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} IndicatorTickSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, @@ -52,7 +52,7 @@ class IndicatorTickSource : public Indicator { /** * Sets indicator data source. */ - void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) override { + void SetDataSource(IndicatorData* _indi, int _input_mode = -1) override { if (_indi == NULL) { // Just deselecting data source. Indicator::SetDataSource(_indi, _input_mode); @@ -112,7 +112,7 @@ class IndicatorTickSource : public Indicator { * Called when user tries to set given data source. Could be used to check if indicator implements all required value * storages. */ - bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) override { + bool OnValidateDataSource(IndicatorData* _ds, string& _reason) override { // @todo Make use of this method. return true; } diff --git a/Indicator/tests/IndicatorTf.test.mq5 b/Indicator/tests/IndicatorTf.test.mq5 index c9cb9d86f..d09b77905 100644 --- a/Indicator/tests/IndicatorTf.test.mq5 +++ b/Indicator/tests/IndicatorTf.test.mq5 @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ diff --git a/Indicator/tests/classes/IndicatorTickDummy.h b/Indicator/tests/classes/IndicatorTickDummy.h index 683025176..823a0d995 100644 --- a/Indicator/tests/classes/IndicatorTickDummy.h +++ b/Indicator/tests/classes/IndicatorTickDummy.h @@ -46,7 +46,7 @@ class IndicatorTickDummy : public IndicatorTick string GetName() override { return "IndicatorTickReal"; } - void OnBecomeDataSourceFor(IndicatorBase* _base_indi) override { + void OnBecomeDataSourceFor(IndicatorData* _indi) override { // Feeding base indicator with historic entries of this indicator. #ifdef __debug__ - Print(GetFullName(), " became a data source for ", _base_indi.GetFullName()); + Print(GetFullName(), " became a data source for ", _indi.GetFullName()); #endif #ifndef __MQL4__ int _ticks_to_emit = 1000; #ifdef __debug_verbose__ - Print(_base_indi.GetFullName(), " will be now filled with ", _ticks_to_emit, + Print(_indi.GetFullName(), " will be now filled with ", _ticks_to_emit, " historical entries generated by " + GetFullName()); #endif @@ -82,7 +82,7 @@ class IndicatorTickReal : public IndicatorTick for (int i = 0; i < _num_copied; ++i) { TickAB _tick(_ticks[i].ask, _ticks[i].bid); // We can't call EmitEntry() here, as tick would go to multiple sources at the same time! - _base_indi.OnDataSourceEntry(TickToEntry(_ticks[i].time, _tick)); + _indi.OnDataSourceEntry(TickToEntry(_ticks[i].time, _tick)); } #endif } diff --git a/Indicator/tests/classes/Indicators.h b/Indicator/tests/classes/Indicators.h index f8258b555..1d1da2066 100644 --- a/Indicator/tests/classes/Indicators.h +++ b/Indicator/tests/classes/Indicators.h @@ -30,23 +30,23 @@ #endif // Includes. -#include "../../../IndicatorBase.h" +#include "../../../IndicatorData.mqh" #include "../../../Refs.mqh" /** * Helper class to store all indicators and call OnTick() on them. */ class Indicators { - Ref _indis[]; + Ref _indis[]; public: void Add(IndicatorBase* _indi) { - Ref _ref = _indi; + Ref _ref = _indi; ArrayPushObject(_indis, _ref); } - void Remove(IndicatorBase* _indi) { - Ref _ref = _indi; + void Remove(IndicatorData* _indi) { + Ref _ref = _indi; Util::ArrayRemoveFirst(_indis, _ref); } diff --git a/IndicatorBase.h b/IndicatorBase.h index 604dec195..df56648b2 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -44,15 +44,11 @@ class Chart; #include "Indicator.struct.cache.h" #include "Indicator.struct.h" #include "Indicator.struct.serialize.h" -#include "Indicator.struct.signal.h" #include "Object.mqh" #include "Refs.mqh" #include "Serializer.mqh" #include "SerializerCsv.mqh" #include "SerializerJson.mqh" -#include "Storage/ValueStorage.h" -#include "Storage/ValueStorage.indicator.h" -#include "Storage/ValueStorage.native.h" #include "Util.h" /** @@ -62,17 +58,10 @@ class IndicatorBase : public Chart { protected: IndicatorState istate; void* mydata; - bool is_fed; // Whether calc_start_bar is already calculated. - int calc_start_bar; // Index of the first valid bar (from 0). - DictStruct> indicators; // Indicators list keyed by id. + int calc_start_bar; // Index of the first valid bar (from 0). bool indicator_builtin; - ARRAY(ValueStorage*, value_storages); - Ref indi_src; // // Indicator used as data source. - int indi_src_mode; // Mode of source indicator - IndicatorCalculateCache cache; - ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. - long last_tick_time; // Time of the last Tick() call. - int flags; // Flags such as INDI_FLAG_INDEXABLE_BY_SHIFT. + long last_tick_time; // Time of the last Tick() call. + int flags; // Flags such as INDI_FLAG_INDEXABLE_BY_SHIFT. public: /* Indicator enumerations */ @@ -92,12 +81,10 @@ class IndicatorBase : public Chart { /** * Class constructor. */ - IndicatorBase(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) : indi_src(NULL), Chart(_tf, _symbol) { + IndicatorBase(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) : Chart(_tf, _symbol) { // By default, indicator is indexable only by shift and data source must be also indexable by shift. flags = INDI_FLAG_INDEXABLE_BY_SHIFT | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT; calc_start_bar = 0; - is_fed = false; - indi_src = NULL; last_tick_time = 0; } @@ -108,53 +95,13 @@ class IndicatorBase : public Chart { // By default, indicator is indexable only by shift and data source must be also indexable by shift. flags = INDI_FLAG_INDEXABLE_BY_SHIFT | INDI_FLAG_SOURCE_REQ_INDEXABLE_BY_SHIFT; calc_start_bar = 0; - is_fed = false; - indi_src = NULL; last_tick_time = 0; } /** * Class deconstructor. */ - virtual ~IndicatorBase() { - ReleaseHandle(); - - for (int i = 0; i < ArraySize(value_storages); ++i) { - if (value_storages[i] != NULL) { - delete value_storages[i]; - } - } - } - - /* Operator overloading methods */ - - /** - * Access indicator entry data using [] operator via shift. - */ - IndicatorDataEntry operator[](int _index) { - if (!bool(flags | INDI_FLAG_INDEXABLE_BY_SHIFT)) { - Print(GetFullName(), " is not indexable by shift!"); - DebugBreak(); - IndicatorDataEntry _default; - return _default; - } - return GetEntry(_index); - } - - /** - * Access indicator entry data using [] operator via datetime. - */ - IndicatorDataEntry operator[](datetime _dt) { - if (!bool(flags | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { - Print(GetFullName(), " is not indexable by timestamp!"); - DebugBreak(); - IndicatorDataEntry _default; - return _default; - } - return GetEntry(_dt); - } - - IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry((int)_index); } + virtual ~IndicatorBase() { ReleaseHandle(); } /* Buffer methods */ @@ -231,120 +178,6 @@ class IndicatorBase : public Chart { } */ - /** - * Gets indicator data from a buffer and copy into struct array. - * - * @return - * Returns true of successful copy. - * Returns false on invalid values. - */ - bool CopyEntries(IndicatorDataEntry& _data[], int _count, int _start_shift = 0) { - bool _is_valid = true; - if (ArraySize(_data) < _count) { - _is_valid &= ArrayResize(_data, _count) > 0; - } - for (int i = 0; i < _count; i++) { - IndicatorDataEntry _entry = GetEntry(_start_shift + i); - _is_valid &= _entry.IsValid(); - _data[i] = _entry; - } - return _is_valid; - } - - /** - * Gets indicator data from a buffer and copy into array of values. - * - * @return - * Returns true of successful copy. - * Returns false on invalid values. - */ - template - bool CopyValues(T& _data[], int _count, int _start_shift = 0, int _mode = 0) { - bool _is_valid = true; - if (ArraySize(_data) < _count) { - _count = ArrayResize(_data, _count); - _count = _count > 0 ? _count : ArraySize(_data); - } - for (int i = 0; i < _count; i++) { - IndicatorDataEntry _entry = GetEntry(_start_shift + i); - _is_valid &= _entry.IsValid(); - _data[i] = (T)_entry[_mode]; - } - return _is_valid; - } - - /** - * Validates currently selected indicator used as data source. - */ - void ValidateSelectedDataSource() { - if (HasDataSource()) { - ValidateDataSource(THIS_PTR, GetDataSourceRaw()); - } - } - - /** - * Loads and validates built-in indicators whose can be used as data source. - */ - virtual void ValidateDataSource(IndicatorBase* _target, IndicatorBase* _source) {} - - /** - * Checks whether indicator have given mode index. - * - * If given mode is -1 (default one) and indicator has exactly one mode, then mode index will be replaced by 0. - */ - virtual void ValidateDataSourceMode(int& _out_mode) {} - - /** - * Provides built-in indicators whose can be used as data source. - */ - virtual IndicatorBase* FetchDataSource(ENUM_INDICATOR_TYPE _id) { return NULL; } - - /** - * Returns currently selected data source without any validation. - */ - IndicatorBase* GetDataSourceRaw() { return indi_src.Ptr(); } - - /** - * Returns given data source type. Used by i*OnIndicator methods if indicator's Calculate() uses other indicators. - */ - IndicatorBase* GetDataSource(ENUM_INDICATOR_TYPE _type) { - IndicatorBase* _result = NULL; - if (indicators.KeyExists((int)_type)) { - _result = indicators[(int)_type].Ptr(); - } else { - Ref _indi = FetchDataSource(_type); - if (!_indi.IsSet()) { - Alert(GetFullName(), " does not define required indicator type ", EnumToString(_type), " for symbol ", - GetSymbol(), ", and timeframe ", GetTf(), "!"); - DebugBreak(); - } else { - indicators.Set((int)_type, _indi); - _result = _indi.Ptr(); - } - } - return _result; - } - - /** - * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on - * some data source. - */ - virtual IndicatorBase* OnDataSourceRequest() { - Print("In order to use IDATA_INDICATOR mode for indicator ", GetFullName(), - " without explicitly selecting an indicator, ", GetFullName(), - " must override OnDataSourceRequest() method and return new instance of data source to be used by default."); - DebugBreak(); - return NULL; - } - - /** - * Creates default, tick based indicator for given applied price. - */ - virtual IndicatorBase* DataSourceRequestReturnDefault(int _applied_price) { - DebugBreak(); - return NULL; - } - /* Getters */ /** @@ -352,11 +185,6 @@ class IndicatorBase : public Chart { */ int GetFlags() { return flags; } - /** - * Returns buffers' cache. - */ - IndicatorCalculateCache* GetCache() { return &cache; } - /** * Gets an indicator's chart parameter value. */ @@ -390,8 +218,6 @@ class IndicatorBase : public Chart { */ virtual IndicatorBase* GetDataSource() { return NULL; } - int GetDataSourceMode() { return indi_src_mode; } - /** * Get indicator type. */ @@ -427,22 +253,6 @@ class IndicatorBase : public Chart { Chart::Set(_param, _value); } - /** - * Adds event listener. - */ - void AddListener(IndicatorBase* _indi) { - WeakRef _ref = _indi; - ArrayPushObject(listeners, _ref); - } - - /** - * Removes event listener. - */ - void RemoveListener(IndicatorBase* _indi) { - WeakRef _ref = _indi; - Util::ArrayRemoveFirst(listeners, _ref); - } - /** * Sets an indicator's state property value. */ @@ -451,16 +261,6 @@ class IndicatorBase : public Chart { istate.Set(_prop, _value); } - /** - * Sets indicator data source. - */ - virtual void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) = NULL; - - /** - * Sets data source's input mode. - */ - void SetDataSourceMode(int _mode) { indi_src_mode = _mode; } - /** * Sets name of the indicator. */ @@ -495,226 +295,10 @@ class IndicatorBase : public Chart { istate.is_changed = true; } - ValueStorage* GetValueStorage(int _mode = 0) { - if (_mode >= ArraySize(value_storages)) { - ArrayResize(value_storages, _mode + 1); - } - - if (value_storages[_mode] == NULL) { - value_storages[_mode] = new IndicatorBufferValueStorage(THIS_PTR, _mode); - } - return value_storages[_mode]; - } - - /** - * Returns value storage of given kind. - */ - virtual IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { - Print("Error: ", GetFullName(), " indicator has no storage type ", EnumToString(_type), "!"); - DebugBreak(); - return NULL; - } - - virtual IValueStorage* GetSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { - switch (_ap) { - case PRICE_ASK: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); - case PRICE_BID: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); - case PRICE_OPEN: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); - case PRICE_HIGH: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); - case PRICE_LOW: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); - case PRICE_CLOSE: - return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); - case PRICE_MEDIAN: - case PRICE_TYPICAL: - case PRICE_WEIGHTED: - default: - Print("Error: Invalid applied price " + EnumToString(_ap) + - ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " - "IndicatorBase::GetSpecificAppliedPriceValueStorage()!"); - DebugBreak(); - return NULL; - } - } - - virtual bool HasSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { - switch (_ap) { - case PRICE_ASK: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); - case PRICE_BID: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); - case PRICE_OPEN: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); - case PRICE_HIGH: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); - case PRICE_LOW: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); - case PRICE_CLOSE: - return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); - case PRICE_MEDIAN: - case PRICE_TYPICAL: - case PRICE_WEIGHTED: - default: - Print("Error: Invalid applied price " + EnumToString(_ap) + - ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " - "IndicatorBase::HasSpecificAppliedPriceValueStorage()!"); - DebugBreak(); - return false; - } - } - - /** - * Checks whether indicator support given value storage type. - */ - virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { return false; } - - template - T GetValue(int _mode = 0, int _index = 0) { - T _out; - GetEntryValue(_mode, _index).Get(_out); - return _out; - } - - /** - * Returns values for a given shift. - * - * Note: Remember to check if shift exists by HasValidEntry(shift). - */ - template - bool GetValues(int _index, T& _out1, T& _out2) { - IndicatorDataEntry _entry = GetEntry(_index); - _out1 = _entry.values[0]; - _out2 = _entry.values[1]; - bool _result = GetLastError() != 4401; - ResetLastError(); - return _result; - } - - template - bool GetValues(int _index, T& _out1, T& _out2, T& _out3) { - IndicatorDataEntry _entry = GetEntry(_index); - _out1 = _entry.values[0]; - _out2 = _entry.values[1]; - _out3 = _entry.values[2]; - bool _result = GetLastError() != 4401; - ResetLastError(); - return _result; - } - - template - bool GetValues(int _index, T& _out1, T& _out2, T& _out3, T& _out4) { - IndicatorDataEntry _entry = GetEntry(_index); - _out1 = _entry.values[0]; - _out2 = _entry.values[1]; - _out3 = _entry.values[2]; - _out4 = _entry.values[3]; - bool _result = GetLastError() != 4401; - ResetLastError(); - return _result; - } - - void Tick() { - long _current_time = TimeCurrent(); - - if (last_tick_time == _current_time) { - // We've already ticked. - return; - } - - last_tick_time = _current_time; - - // Checking and potentially initializing new data source. - if (HasDataSource(true) != NULL) { - // Ticking data source if not yet ticked. - GetDataSource().Tick(); - } - - // Also ticking all used indicators if they've not yet ticked. - for (DictStructIterator> iter = indicators.Begin(); iter.IsValid(); ++iter) { - iter.Value().Ptr().Tick(); - } - - // Overridable OnTick() method. - OnTick(); - } - - virtual void OnTick() {} - /* Data representation methods */ /* Virtual methods */ - /** - * Returns the indicator's struct value. - */ - virtual IndicatorDataEntry GetEntry(int _index = 0) = NULL; - - /** - * Returns the indicator's struct value. - */ - virtual IndicatorDataEntry GetEntry(datetime _dt) { - Print(GetFullName(), - " must implement IndicatorDataEntry IndicatorBase::GetEntry(datetime _dt) in order to use GetEntry(datetime " - "_dt) or _indi[datetime] subscript operator!"); - DebugBreak(); - IndicatorDataEntry _default; - return _default; - } - - /** - * Alters indicator's struct value. - * - * This method allows user to modify the struct entry before it's added to cache. - * This method is called on GetEntry() right after values are set. - */ - virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _index = -1) = NULL; - - // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = NULL; - - /** - * Returns the indicator's entry value. - */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) = NULL; - - /** - * Sends entry to listening indicators. - */ - void EmitEntry(IndicatorDataEntry& entry) { - for (int i = 0; i < ArraySize(listeners); ++i) { - if (listeners[i].ObjectExists()) { - listeners[i].Ptr().OnDataSourceEntry(entry); - } - } - } - - /** - * Sends historic entries to listening indicators. May be overriden. - */ - virtual void EmitHistory() {} - - /** - * Called when data source emits new entry (historic or future one). - */ - virtual void OnDataSourceEntry(IndicatorDataEntry& entry){}; - - /** - * Called when indicator became a data source for other indicator. - */ - virtual void OnBecomeDataSourceFor(IndicatorBase* _base_indi){}; - - /** - * Called when user tries to set given data source. Could be used to check if indicator implements all required value - * storages. - */ - virtual bool OnValidateDataSource(IndicatorBase* _ds, string& _reason) { - _reason = "Indicator " + GetName() + " does not implement OnValidateDataSource()"; - return false; - } - /** * Returns indicator value for a given shift and mode. */ @@ -736,59 +320,6 @@ class IndicatorBase : public Chart { */ // virtual bool ToString() = NULL; // @fixme? - /** - * Whether we can and have to select mode when specifying data source. - */ - virtual bool IsDataSourceModeSelectable() { return true; } - - /** - * Update indicator. - */ - virtual bool Update() { - // @todo - return false; - }; - - /** - * Returns the indicator's value in plain format. - */ - virtual string ToString(int _index = 0) { - IndicatorDataEntry _entry = GetEntry(_index); - int _serializer_flags = SERIALIZER_FLAG_SKIP_HIDDEN | SERIALIZER_FLAG_INCLUDE_DEFAULT | - SERIALIZER_FLAG_INCLUDE_DYNAMIC | SERIALIZER_FLAG_INCLUDE_FEATURE; - - IndicatorDataEntry _stub_entry; - _stub_entry.AddFlags(_entry.GetFlags()); - SerializerConverter _stub = SerializerConverter::MakeStubObject(_stub_entry, _serializer_flags, _entry.GetSize()); - return SerializerConverter::FromObject(_entry, _serializer_flags).ToString(0, &_stub); - } - - int GetBarsCalculated() { - int _bars = Bars(GetSymbol(), GetTf()); - - if (!is_fed) { - // Calculating start_bar. - for (; calc_start_bar < _bars; ++calc_start_bar) { - // Iterating from the oldest or previously iterated. - IndicatorDataEntry _entry = GetEntry(_bars - calc_start_bar - 1); - - if (_entry.IsValid()) { - // From this point we assume that future entries will be all valid. - is_fed = true; - return _bars - calc_start_bar; - } - } - } - - if (!is_fed) { - Print("Can't find valid bars for ", GetFullName()); - return 0; - } - - // Assuming all entries are calculated (even if have invalid values). - return _bars; - } - /* Methods to get rid of */ /** @@ -933,41 +464,3 @@ class IndicatorBase : public Chart { #endif } }; - -/** - * CopyBuffer() method to be used on Indicator instance with ValueStorage buffer. - * - * Note that data will be copied so that the oldest element will be located at the start of the physical memory - * allocated for the array - */ -template -int CopyBuffer(IndicatorBase* _indi, int _mode, int _start, int _count, ValueStorage& _buffer, int _rates_total) { - int _num_copied = 0; - int _buffer_size = ArraySize(_buffer); - - if (_buffer_size < _rates_total) { - _buffer_size = ArrayResize(_buffer, _rates_total); - } - - for (int i = _start; i < _count; ++i) { - IndicatorDataEntry _entry = _indi.GetEntry(i); - - if (!_entry.IsValid()) { - break; - } - - T _value = _entry.GetValue(_mode); - - // Print(_value); - - _buffer[_buffer_size - i - 1] = _value; - ++_num_copied; - } - - return _num_copied; -} - -/** - * BarsCalculated()-compatible method to be used on Indicator instance. - */ -int BarsCalculated(IndicatorBase* _indi) { return _indi.GetBarsCalculated(); } diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 242eb038a..0db969639 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ @@ -21,277 +21,605 @@ */ // Includes. -#include "Chart.mqh" -#include "Indicator.mqh" -#include "Log.mqh" - -#define TO_STRING_LIMIT_DEFAULT 3 -#define INDICATOR_BUFFERS_COUNT_MIN 1 -#define BUFFER_MAX_SIZE_DEFAULT 50 +#include "IndicatorBase.h" +#include "IndicatorData.struct.h" +#include "IndicatorData.struct.serialize.h" +#include "IndicatorData.struct.signal.h" +#include "Storage/ValueStorage.h" +#include "Storage/ValueStorage.indicator.h" +#include "Storage/ValueStorage.native.h" /** - * Class to store indicator value. + * Implements class to store indicator data. */ -class IndicatorValue { +class IndicatorData : public IndicatorBase { + protected: + // Class variables. + ARRAY(ValueStorage*, value_storages); + ARRAY(WeakRef, listeners); // List of indicators that listens for events from this one. + BufferStruct idata; + DictStruct> indicators; // Indicators list keyed by id. + IndicatorCalculateCache cache; + Ref indi_src; // // Indicator used as data source. + bool is_fed; // Whether calc_start_bar is already calculated. + int indi_src_mode; // Mode of source indicator + public: - datetime bt; // bar time - MqlParam value; // Contains value based on the data type (real, integer or string type). + /* Special methods */ - // double linked list attrs - IndicatorValue* prev; - IndicatorValue* next; + /** + * Class constructor. + */ + IndicatorData(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) + : indi_src(NULL), is_fed(false), IndicatorBase(_tf, _symbol) {} - void IndicatorValue() : bt(NULL), prev(NULL), next(NULL) {} + /** + * Class constructor. + */ + IndicatorData(ENUM_TIMEFRAMES_INDEX _tfi, string _symbol = NULL) : IndicatorBase(_tfi, _symbol) {} - // double linked list methods - void Prev(IndicatorValue* p) { - if (CheckPointer(p) == POINTER_INVALID) return; - prev = p; - p.next = GetPointer(this); - } - void Next(IndicatorValue* p) { - if (CheckPointer(p) == POINTER_INVALID) return; - next = p; - p.prev = GetPointer(this); + /** + * Class deconstructor. + */ + virtual ~IndicatorData() { + for (int i = 0; i < ArraySize(value_storages); ++i) { + if (value_storages[i] != NULL) { + delete value_storages[i]; + } + } } -}; -/** - * Class to manage data buffer. - */ -class IndicatorBuffer { - protected: - int size; - int max_size; - IndicatorValue* _head; - IndicatorValue* _tail; + /* Operator overloading methods */ - public: - IndicatorBuffer(int _max_size = BUFFER_MAX_SIZE_DEFAULT) : size(0), max_size(_max_size), _head(NULL), _tail(NULL) {} - ~IndicatorBuffer() { - IndicatorValue* it = NULL; - while (CheckPointer(_head) == POINTER_DYNAMIC) { - it = _head; - _head = _head.prev; - delete it; + /** + * Access indicator entry data using [] operator via shift. + */ + IndicatorDataEntry operator[](int _index) { + if (!bool(flags | INDI_FLAG_INDEXABLE_BY_SHIFT)) { + Print(GetFullName(), " is not indexable by shift!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; } + return GetEntry(_index); } - double GetDouble(datetime _bar_time) { - if (CheckPointer(_head) == POINTER_INVALID) return 0; + /** + * Access indicator entry data using [] operator via datetime. + */ + IndicatorDataEntry operator[](datetime _dt) { + if (!bool(flags | INDI_FLAG_INDEXABLE_BY_TIMESTAMP)) { + Print(GetFullName(), " is not indexable by timestamp!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; + } + return GetEntry(_dt); + } + + IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry((int)_index); } + + /* Data methods */ - IndicatorValue* _target = _head; - while (CheckPointer(_target) == POINTER_DYNAMIC && (_bar_time < _target.bt || _target.value.type != TYPE_DOUBLE)) { - _target = _target.prev; + /** + * Gets indicator data from a buffer and copy into struct array. + * + * @return + * Returns true of successful copy. + * Returns false on invalid values. + */ + bool CopyEntries(IndicatorDataEntry& _data[], int _count, int _start_shift = 0) { + bool _is_valid = true; + if (ArraySize(_data) < _count) { + _is_valid &= ArrayResize(_data, _count) > 0; + } + for (int i = 0; i < _count; i++) { + IndicatorDataEntry _entry = GetEntry(_start_shift + i); + _is_valid &= _entry.IsValid(); + _data[i] = _entry; } + return _is_valid; + } - if (CheckPointer(_target) == POINTER_INVALID) return 0; + /** + * Gets indicator data from a buffer and copy into array of values. + * + * @return + * Returns true of successful copy. + * Returns false on invalid values. + */ + template + bool CopyValues(T& _data[], int _count, int _start_shift = 0, int _mode = 0) { + bool _is_valid = true; + if (ArraySize(_data) < _count) { + _count = ArrayResize(_data, _count); + _count = _count > 0 ? _count : ArraySize(_data); + } + for (int i = 0; i < _count; i++) { + IndicatorDataEntry _entry = GetEntry(_start_shift + i); + _is_valid &= _entry.IsValid(); + _data[i] = (T)_entry[_mode]; + } + return _is_valid; + } + + /* Getters */ + + int GetBarsCalculated() { + int _bars = Bars(GetSymbol(), GetTf()); + + if (!is_fed) { + // Calculating start_bar. + for (; calc_start_bar < _bars; ++calc_start_bar) { + // Iterating from the oldest or previously iterated. + IndicatorDataEntry _entry = GetEntry(_bars - calc_start_bar - 1); - if (_target.bt == _bar_time && _target.value.type == TYPE_DOUBLE) - return _target.value.double_value; - else + if (_entry.IsValid()) { + // From this point we assume that future entries will be all valid. + is_fed = true; + return _bars - calc_start_bar; + } + } + } + + if (!is_fed) { + Print("Can't find valid bars for ", GetFullName()); return 0; + } + + // Assuming all entries are calculated (even if have invalid values). + return _bars; } - int GetInt(datetime _bar_time) { - if (CheckPointer(_head) == POINTER_INVALID) return 0; + /** + * Returns buffers' cache. + */ + IndicatorCalculateCache* GetCache() { return &cache; } + + /** + * Get pointer to data of indicator. + */ + BufferStruct* GetData() { return GetPointer(idata); } - IndicatorValue* _target = _head; - while (CheckPointer(_target) == POINTER_DYNAMIC && (_bar_time < _target.bt || _target.value.type != TYPE_INT)) { - _target = _target.prev; + /** + * Returns given data source type. Used by i*OnIndicator methods if indicator's Calculate() uses other indicators. + */ + IndicatorData* GetDataSource(ENUM_INDICATOR_TYPE _type) { + IndicatorData* _result = NULL; + if (indicators.KeyExists((int)_type)) { + _result = indicators[(int)_type].Ptr(); + } else { + Ref _indi = FetchDataSource(_type); + if (!_indi.IsSet()) { + Alert(GetFullName(), " does not define required indicator type ", EnumToString(_type), " for symbol ", + GetSymbol(), ", and timeframe ", GetTf(), "!"); + DebugBreak(); + } else { + indicators.Set((int)_type, _indi); + _result = _indi.Ptr(); + } } + return _result; + } - if (CheckPointer(_target) == POINTER_INVALID) return 0; + int GetDataSourceMode() { return indi_src_mode; } - if (_target.bt == _bar_time && _target.value.type == TYPE_INT) - return (int)_target.value.integer_value; - else - return 0; + /** + * Returns currently selected data source without any validation. + */ + IndicatorBase* GetDataSourceRaw() { return indi_src.Ptr(); } + + /** + * Returns values for a given shift. + * + * Note: Remember to check if shift exists by HasValidEntry(shift). + */ + template + bool GetValues(int _index, T& _out1, T& _out2) { + IndicatorDataEntry _entry = GetEntry(_index); + _out1 = _entry.values[0]; + _out2 = _entry.values[1]; + bool _result = GetLastError() != 4401; + ResetLastError(); + return _result; } - bool Add(double _value, datetime _bar_time, bool _force = false) { - IndicatorValue* new_value = new IndicatorValue(); - new_value.bt = _bar_time; - new_value.value.type = TYPE_DOUBLE; - new_value.value.double_value = _value; - return AddIndicatorValue(new_value, _force); + template + bool GetValues(int _index, T& _out1, T& _out2, T& _out3) { + IndicatorDataEntry _entry = GetEntry(_index); + _out1 = _entry.values[0]; + _out2 = _entry.values[1]; + _out3 = _entry.values[2]; + bool _result = GetLastError() != 4401; + ResetLastError(); + return _result; } - bool Add(int _value, datetime _bar_time, bool _force = false) { - IndicatorValue* new_value = new IndicatorValue(); - new_value.bt = _bar_time; - new_value.value.type = TYPE_INT; - new_value.value.integer_value = _value; - return AddIndicatorValue(new_value, _force); + template + bool GetValues(int _index, T& _out1, T& _out2, T& _out3, T& _out4) { + IndicatorDataEntry _entry = GetEntry(_index); + _out1 = _entry.values[0]; + _out2 = _entry.values[1]; + _out3 = _entry.values[2]; + _out4 = _entry.values[3]; + bool _result = GetLastError() != 4401; + ResetLastError(); + return _result; } - bool AddIndicatorValue(IndicatorValue* _new_value, bool _force = false) { - if (CheckPointer(_new_value) == POINTER_INVALID) return false; + /** + * Provides built-in indicators whose can be used as data source. + */ + virtual IndicatorBase* FetchDataSource(ENUM_INDICATOR_TYPE _id) { return NULL; } + + /* Checkers */ + + /** + * Whether we can and have to select mode when specifying data source. + */ + virtual bool IsDataSourceModeSelectable() { return true; } - // first node for empty linked list - if (CheckPointer(_head) == POINTER_INVALID) { - _head = _new_value; - _tail = _new_value; - size = 1; - return true; + /* Setters */ + + /** + * Adds event listener. + */ + void AddListener(IndicatorData* _indi) { + WeakRef _ref = _indi; + ArrayPushObject(listeners, _ref); + } + + /** + * Removes event listener. + */ + void RemoveListener(IndicatorData* _indi) { + WeakRef _ref = _indi; + Util::ArrayRemoveFirst(listeners, _ref); + } + + /** + * Sets data source's input mode. + */ + void SetDataSourceMode(int _mode) { indi_src_mode = _mode; } + + /* Storage methods */ + + ValueStorage* GetValueStorage(int _mode = 0) { + if (_mode >= ArraySize(value_storages)) { + ArrayResize(value_storages, _mode + 1); } - // find insert position - IndicatorValue* insert_pos = _head; - while (CheckPointer(insert_pos) == POINTER_DYNAMIC && _new_value.bt <= insert_pos.bt) { - insert_pos = insert_pos.prev; + if (value_storages[_mode] == NULL) { + value_storages[_mode] = new IndicatorBufferValueStorage(THIS_PTR, _mode); } + return value_storages[_mode]; + } - // find existed value node(match both bt and value.type), force replace or not - if (CheckPointer(insert_pos) == POINTER_DYNAMIC && _new_value.bt == insert_pos.bt && - _new_value.value.type == insert_pos.value.type) { - if (_force) { - insert_pos.value.integer_value = _new_value.value.integer_value; - insert_pos.value.double_value = _new_value.value.double_value; - insert_pos.value.string_value = _new_value.value.string_value; - return true; - } else + /** + * Returns value storage of given kind. + */ + virtual IValueStorage* GetSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { + Print("Error: ", GetFullName(), " indicator has no storage type ", EnumToString(_type), "!"); + DebugBreak(); + return NULL; + } + + virtual IValueStorage* GetSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { + switch (_ap) { + case PRICE_ASK: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); + case PRICE_BID: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); + case PRICE_OPEN: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + case PRICE_HIGH: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + case PRICE_LOW: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + case PRICE_CLOSE: + return GetSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + default: + Print("Error: Invalid applied price " + EnumToString(_ap) + + ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " + "IndicatorBase::GetSpecificAppliedPriceValueStorage()!"); + DebugBreak(); + return NULL; + } + } + + virtual bool HasSpecificAppliedPriceValueStorage(ENUM_APPLIED_PRICE _ap) { + switch (_ap) { + case PRICE_ASK: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_ASK); + case PRICE_BID: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_BID); + case PRICE_OPEN: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_OPEN); + case PRICE_HIGH: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_HIGH); + case PRICE_LOW: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_LOW); + case PRICE_CLOSE: + return HasSpecificValueStorage(INDI_VS_TYPE_PRICE_CLOSE); + case PRICE_MEDIAN: + case PRICE_TYPICAL: + case PRICE_WEIGHTED: + default: + Print("Error: Invalid applied price " + EnumToString(_ap) + + ", only PRICE_(OPEN|HIGH|LOW|CLOSE) are currently supported by " + "IndicatorBase::HasSpecificAppliedPriceValueStorage()!"); + DebugBreak(); return false; } + } + + /** + * Checks whether indicator support given value storage type. + */ + virtual bool HasSpecificValueStorage(ENUM_INDI_VS_TYPE _type) { return false; } + + /* Tick methods */ + + void Tick() { + long _current_time = TimeCurrent(); + + if (last_tick_time == _current_time) { + // We've already ticked. + return; + } + + last_tick_time = _current_time; - // find insert pos at end of linked list - if (CheckPointer(insert_pos) == POINTER_INVALID) { - _tail.Prev(_new_value); - _tail = _new_value; + // Checking and potentially initializing new data source. + if (HasDataSource(true) != NULL) { + // Ticking data source if not yet ticked. + GetDataSource().Tick(); } - // find insert pos at begin of linked list - else if (insert_pos == _head) { - _head.Next(_new_value); - _head = _new_value; + + // Also ticking all used indicators if they've not yet ticked. + for (DictStructIterator> iter = indicators.Begin(); iter.IsValid(); ++iter) { + iter.Value().Ptr().Tick(); } - // find insert pos at normal place - else { - insert_pos.Next(_new_value); + + // Overridable OnTick() method. + OnTick(); + } + + /* Validate methods */ + + /** + * Loads and validates built-in indicators whose can be used as data source. + */ + void ValidateDataSource(IndicatorData* _target, IndicatorData* _source) { + if (_target == NULL) { + Alert("Internal Error! _target is NULL in ", __FUNCTION_LINE__, "."); + DebugBreak(); + return; } - size++; - - // truncate data out of max_size - if (size > max_size) { - for (int i = 0; i < (max_size - size); i++) { - _tail = _tail.next; - delete _tail.prev; - size--; - } + + if (_source == NULL) { + Alert("Error! You have to select source indicator's via SetDataSource()."); + DebugBreak(); + return; } - return true; + if (!_target.IsDataSourceModeSelectable()) { + // We don't validate source mode as it will use all modes. + return; + } + + if (_source.GetModeCount() > 1 && _target.GetDataSourceMode() == -1) { + // Mode must be selected if source indicator has more that one mode. + Alert("Warning! ", GetName(), + " must select source indicator's mode via SetDataSourceMode(int). Defaulting to mode 0."); + _target.SetDataSourceMode(0); + DebugBreak(); + } else if (_source.GetModeCount() == 1 && _target.GetDataSourceMode() == -1) { + _target.SetDataSourceMode(0); + } else if (_target.GetDataSourceMode() < 0 || _target.GetDataSourceMode() > _source.GetModeCount()) { + Alert("Error! ", _target.GetName(), + " must select valid source indicator's mode via SetDataSourceMode(int) between 0 and ", + _source.GetModeCount(), "."); + DebugBreak(); + } } - string ToString(uint _limit = TO_STRING_LIMIT_DEFAULT) { - string out = NULL; - IndicatorValue* it = _head; - uint i = 0; - while (CheckPointer(it) == POINTER_DYNAMIC && i < _limit) { - if (out != NULL) - // add comma - out = StringFormat("%s, ", out); - else - out = ""; - - switch (it.value.type) { - case TYPE_INT: - out = StringFormat("%s[%d]%d", out, i, it.value.integer_value); - break; - case TYPE_DOUBLE: { - string strfmt = StringFormat("%%s[%%d]%%.%df", _Digits); - out = StringFormat(strfmt, out, i, it.value.double_value); - break; - } - } - i++; - it = it.prev; + /** + * Validates currently selected indicator used as data source. + */ + void ValidateSelectedDataSource() { + if (HasDataSource()) { + ValidateDataSource(THIS_PTR, GetDataSourceRaw()); } - if (out == "" || out == NULL) out = "[Empty]"; - return out; } -}; -/** - * Implements class to store indicator data. - */ -class IndicatorData : public Chart { - protected: - // Struct variables. - IndicatorBuffer buffers[]; + /* Printers */ - string iname; + /** + * Returns the indicator's value in plain format. + */ + virtual string ToString(int _index = 0) { + IndicatorDataEntry _entry = GetEntry(_index); + int _serializer_flags = SERIALIZER_FLAG_SKIP_HIDDEN | SERIALIZER_FLAG_INCLUDE_DEFAULT | + SERIALIZER_FLAG_INCLUDE_DYNAMIC | SERIALIZER_FLAG_INCLUDE_FEATURE; + + IndicatorDataEntry _stub_entry; + _stub_entry.AddFlags(_entry.GetFlags()); + SerializerConverter _stub = SerializerConverter::MakeStubObject(_stub_entry, _serializer_flags, _entry.GetSize()); + return SerializerConverter::FromObject(_entry, _serializer_flags).ToString(0, &_stub); + } - // Logging. - Ref indi_logger; + template + T GetValue(int _mode = 0, int _index = 0) { + T _out; + GetEntryValue(_mode, _index).Get(_out); + return _out; + } + + /* Virtual methods */ - public: /** - * Class constructor. + * Returns currently selected data source doing validation. + */ + virtual IndicatorData* GetDataSource() { return NULL; } + + /** + * Returns the indicator's struct value. */ - void IndicatorData(string _name = NULL, uint _max_buffer = INDICATOR_BUFFERS_COUNT_MIN) : iname(_name) { - _max_buffer = fmax(_max_buffer, INDICATOR_BUFFERS_COUNT_MIN); - ArrayResize(buffers, _max_buffer); + virtual IndicatorDataEntry GetEntry(datetime _dt) { + Print(GetFullName(), + " must implement IndicatorDataEntry IndicatorBase::GetEntry(datetime _dt) in order to use GetEntry(datetime " + "_dt) or _indi[datetime] subscript operator!"); + DebugBreak(); + IndicatorDataEntry _default; + return _default; } /** - * Class deconstructor. + * Returns the indicator's struct value. */ - void ~IndicatorData() {} + virtual IndicatorDataEntry GetEntry(int _index = 0) = NULL; /** - * Store a new indicator value. + * Alters indicator's struct value. + * + * This method allows user to modify the struct entry before it's added to cache. + * This method is called on GetEntry() right after values are set. */ - bool IsValidMode(uint _mode) { return _mode < (uint)ArraySize(buffers); } + virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _index = -1) = NULL; - bool Add(double _value, uint _mode = 0, uint _shift = CURR, bool _force = false) { - if (!IsValidMode(_mode)) return false; - return buffers[_mode].Add(_value, GetBarTime(_shift), _force); - } + // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = NULL; - bool Add(int _value, uint _mode = 0, uint _shift = CURR, bool _force = false) { - if (!IsValidMode(_mode)) return false; - return buffers[_mode].Add(_value, GetBarTime(_shift), _force); - } + /** + * Returns the indicator's entry value. + */ + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) = NULL; - double GetDouble(uint _mode = 0, uint _shift = CURR) { - if (!IsValidMode(_mode)) return 0; - return buffers[_mode].GetDouble(GetBarTime(_shift)); + /** + * Gets indicator's signals. + * + * When indicator values are not valid, returns empty signals. + */ + virtual IndicatorSignal GetSignals(int _count = 3, int _shift = 0, int _mode1 = 0, int _mode2 = 0) = NULL; + + /** + * Sends entry to listening indicators. + */ + void EmitEntry(IndicatorDataEntry& entry) { + for (int i = 0; i < ArraySize(listeners); ++i) { + if (listeners[i].ObjectExists()) { + listeners[i].Ptr().OnDataSourceEntry(entry); + } + } } - int GetInt(uint _mode = 0, uint _shift = CURR) { - if (!IsValidMode(_mode)) return 0; - return buffers[_mode].GetInt(GetBarTime(_shift)); + /** + * Sends historic entries to listening indicators. May be overriden. + */ + virtual void EmitHistory() {} + + /** + * Called when indicator became a data source for other indicator. + */ + virtual void OnBecomeDataSourceFor(IndicatorData* _base_indi){}; + + /** + * Called when data source emits new entry (historic or future one). + */ + virtual void OnDataSourceEntry(IndicatorDataEntry& entry){}; + + virtual void OnTick() {} + + /** + * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on + * some data source. + */ + virtual IndicatorData* OnDataSourceRequest() { + Print("In order to use IDATA_INDICATOR mode for indicator ", GetFullName(), + " without explicitly selecting an indicator, ", GetFullName(), + " must override OnDataSourceRequest() method and return new instance of data source to be used by default."); + DebugBreak(); + return NULL; } /** - * Get name of the indicator. + * Creates default, tick based indicator for given applied price. */ - string GetName() { return iname != NULL ? iname : "Custom"; } + virtual IndicatorData* DataSourceRequestReturnDefault(int _applied_price) { + DebugBreak(); + return NULL; + } /** - * Print stored data. + * Called when user tries to set given data source. Could be used to check if indicator implements all required value + * storages. */ - string ToString(int mode = -1, uint _limit = TO_STRING_LIMIT_DEFAULT) { - string _out = StringFormat("%s DATA:\n", GetName()); - if (mode == -1) { // print all series - for (int m = 0; m < ArraySize(buffers); m++) { - _out = StringFormat("%s mode=%d %s\n", _out, m, buffers[m].ToString(_limit)); - } - } else if (mode < ArraySize(buffers)) { - _out = StringFormat("%s mode(%d) %s\n", _out, mode, buffers[mode].ToString(_limit)); - } else { - _out = StringFormat("%s [Err] mode(%d) is invalid", mode); - } - return _out; + virtual bool OnValidateDataSource(IndicatorData* _ds, string& _reason) { + _reason = "Indicator " + GetName() + " does not implement OnValidateDataSource()"; + return false; } /** - * Print stored data. + * Sets indicator data source. */ - void PrintData(int mode = -1, uint _limit = TO_STRING_LIMIT_DEFAULT) { Print(ToString(mode, _limit)); } + virtual void SetDataSource(IndicatorData* _indi, int _input_mode = -1) = NULL; /** * Update indicator. */ - bool Update() { return true; } + virtual bool Update() { + // @todo + return false; + }; + + /** + * Loads and validates built-in indicators whose can be used as data source. + */ + // virtual void ValidateDataSource(IndicatorData* _target, IndicatorData* _source) {} + + /** + * Checks whether indicator have given mode index. + * + * If given mode is -1 (default one) and indicator has exactly one mode, then mode index will be replaced by 0. + */ + virtual void ValidateDataSourceMode(int& _out_mode) {} }; + +/** + * BarsCalculated()-compatible method to be used on Indicator instance. + */ +int BarsCalculated(IndicatorData* _indi) { return _indi.GetBarsCalculated(); } + +/** + * CopyBuffer() method to be used on Indicator instance with ValueStorage buffer. + * + * Note that data will be copied so that the oldest element will be located at the start of the physical memory + * allocated for the array + */ +template +int CopyBuffer(IndicatorData* _indi, int _mode, int _start, int _count, ValueStorage& _buffer, int _rates_total) { + int _num_copied = 0; + int _buffer_size = ArraySize(_buffer); + + if (_buffer_size < _rates_total) { + _buffer_size = ArrayResize(_buffer, _rates_total); + } + + for (int i = _start; i < _count; ++i) { + IndicatorDataEntry _entry = _indi.GetEntry(i); + + if (!_entry.IsValid()) { + break; + } + + T _value = _entry.GetValue(_mode); + + _buffer[_buffer_size - i - 1] = _value; + ++_num_copied; + } + + return _num_copied; +} diff --git a/IndicatorData.struct.h b/IndicatorData.struct.h new file mode 100644 index 000000000..d95a547c2 --- /dev/null +++ b/IndicatorData.struct.h @@ -0,0 +1,385 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Includes IndicatorData's structs. + */ + +// Includes. +#include "SerializerNode.enum.h" + +// Type-less value for IndicatorDataEntryValue structure. +union IndicatorDataEntryTypelessValue { + double vdbl; + float vflt; + int vint; + long vlong; +}; + +// Type-aware value for IndicatorDataEntry class. +struct IndicatorDataEntryValue { + unsigned char flags; + IndicatorDataEntryTypelessValue value; + + // Returns type of the value. + ENUM_DATATYPE GetDataType() { return (ENUM_DATATYPE)((flags & 0xF0) >> 4); } + + // Sets type of the value. + void SetDataType(ENUM_DATATYPE _type) { + // Clearing type. + flags &= 0x0F; + + // Setting type. + flags |= (unsigned char)_type << 4; + } + + // Union operators. + template + T operator*(const T _value) { + return Get() * _value; + } + template + T operator+(const T _value) { + return Get() + _value; + } + template + T operator-(const T _value) { + return Get() - _value; + } + template + T operator/(const T _value) { + return Get() / _value; + } + template + bool operator!=(const T _value) { + return Get() != _value; + } + template + bool operator<(const T _value) { + return Get() < _value; + } + template + bool operator<=(const T _value) { + return Get() <= _value; + } + template + bool operator==(const T _value) { + return Get() == _value; + } + template + bool operator>(const T _value) { + return Get() > _value; + } + template + bool operator>=(const T _value) { + return Get() >= _value; + } + template + void operator=(const T _value) { + Set(_value); + } + // Checkers. + template + bool IsGt(T _value) { + return Get() > _value; + } + template + bool IsLt(T _value) { + return Get() < _value; + } + // Getters. + double GetDbl() { return value.vdbl; } + float GetFloat() { return value.vflt; } + int GetInt() { return value.vint; } + long GetLong() { return value.vlong; } + template + void Get(T &_out) { + _out = Get(); + } + template + T Get() { + T _v; + Get(_v); + return _v; + } + void Get(double &_out) { _out = value.vdbl; } + void Get(float &_out) { _out = value.vflt; } + void Get(int &_out) { _out = value.vint; } + void Get(unsigned int &_out) { _out = (unsigned int)value.vint; } + void Get(long &_out) { _out = value.vlong; } + void Get(unsigned long &_out) { _out = (unsigned long)value.vint; } + // Setters. + template + void Set(T _value) { + Set(_value); + } + void Set(double _value) { + value.vdbl = _value; + SetDataType(TYPE_DOUBLE); + } + void Set(float _value) { + value.vflt = _value; + SetDataType(TYPE_FLOAT); + } + void Set(int _value) { + value.vint = _value; + SetDataType(TYPE_INT); + } + void Set(unsigned int _value) { + value.vint = (int)_value; + SetDataType(TYPE_UINT); + } + void Set(long _value) { + value.vlong = _value; + SetDataType(TYPE_LONG); + } + void Set(unsigned long _value) { + value.vlong = (long)_value; + SetDataType(TYPE_ULONG); + } + // Serializers. + // SERIALIZER_EMPTY_STUB + SerializerNodeType Serialize(Serializer &_s); + // To string + template + string ToString() { + return (string)Get(); + } +}; + +/* Structure for indicator data entry. */ +struct IndicatorDataEntry { + long timestamp; // Timestamp of the entry's bar. + unsigned short flags; // Indicator entry flags. + ARRAY(IndicatorDataEntryValue, values); + + // Constructors. + IndicatorDataEntry(int _size = 1) : flags(INDI_ENTRY_FLAG_NONE), timestamp(0) { Resize(_size); } + IndicatorDataEntry(IndicatorDataEntry &_entry) { THIS_REF = _entry; } + int GetSize() { return ArraySize(values); } + // Operator overloading methods. + template + T operator*(const T _value) { + return values[0].Get() * _value; + } + template + T operator+(const T _value) { + return values[0].Get() + _value; + } + template + T operator-(const T _value) { + return values[0].Get() - _value; + } + template + T operator/(const T _value) { + return values[0].Get() / _value; + } + template + T operator[](I _index) { + return values[(int)_index].Get(); + } + template <> + double operator[](int _index) { + if (_index >= ArraySize(values)) { + return 0; + } + double _value; + values[_index].Get(_value); + return _value; + } + // Checkers. + template + bool HasValue(T _value) { + bool _result = false; + int _asize = ArraySize(values); + T _value2; + for (int i = 0; i < _asize; i++) { + values[i].Get(_value2); + if (_value == _value2) { + _result = true; + break; + } + } + return _result; + } + template + bool IsGe(T _value) { + return GetMin() >= _value; + } + template + bool IsGt(T _value) { + return GetMin() > _value; + } + template + bool IsLe(T _value) { + return GetMax() <= _value; + } + template + bool IsLt(T _value) { + return GetMax() < _value; + } + template + bool IsWithinRange(T _min, T _max) { + return GetMin() >= _min && GetMax() <= _max; + } + // Getters. + template + void GetArray(ARRAY_REF(T, _out), int _size = 0) { + int _asize = _size > 0 ? _size : ArraySize(_out); + for (int i = 0; i < _asize; i++) { + values[i].Get(_out[i]); + } + }; + template + T GetAvg(int _size = 0) { + int _asize = _size > 0 ? _size : ArraySize(values); + T _avg = GetSum() / _asize; + return _avg; + }; + template + T GetMin(int _size = 0) { + int _asize = _size > 0 ? _size : ArraySize(values); + int _index = 0; + for (int i = 1; i < _asize; i++) { + _index = values[i].Get() < values[_index].Get() ? i : _index; + } + return values[_index].Get(); + }; + template + T GetMax(int _size = 0) { + int _asize = _size > 0 ? _size : ArraySize(values); + int _index = 0; + for (int i = 1; i < _asize; i++) { + _index = values[i].Get() > values[_index].Get() ? i : _index; + } + return values[_index].Get(); + }; + template + T GetSum(int _size = 0) { + int _asize = _size > 0 ? _size : ArraySize(values); + T _sum = 0; + for (int i = 1; i < _asize; i++) { + _sum = +values[i].Get(); + } + return _sum; + }; + template + T GetValue(int _index = 0) { + return values[_index].Get(); + }; + template + void GetValues(T &_out1, T &_out2) { + values[0].Get(_out1); + values[1].Get(_out2); + }; + template + void GetValues(T &_out1, T &_out2, T &_out3) { + values[0].Get(_out1); + values[1].Get(_out2); + values[2].Get(_out3); + }; + template + void GetValues(T &_out1, T &_out2, T &_out3, T &_out4) { + values[0].Get(_out1); + values[1].Get(_out2); + values[2].Get(_out3); + values[3].Get(_out4); + }; + + // Getters. + int GetDayOfYear() { return DateTimeStatic::DayOfYear(timestamp); } + int GetMonth() { return DateTimeStatic::Month(timestamp); } + int GetYear() { return DateTimeStatic::Year(timestamp); } + long GetTime() { return timestamp; }; + ENUM_DATATYPE GetDataType(int _mode) { return values[_mode].GetDataType(); } + ushort GetDataTypeFlags(ENUM_DATATYPE _dt) { + switch (_dt) { + case TYPE_BOOL: + case TYPE_CHAR: + SetUserError(ERR_INVALID_PARAMETER); + break; + case TYPE_INT: + return INDI_ENTRY_FLAG_NONE; + case TYPE_LONG: + return INDI_ENTRY_FLAG_IS_DOUBLED; + case TYPE_UINT: + return INDI_ENTRY_FLAG_IS_UNSIGNED; + case TYPE_ULONG: + return INDI_ENTRY_FLAG_IS_UNSIGNED | INDI_ENTRY_FLAG_IS_DOUBLED; + case TYPE_DOUBLE: + return INDI_ENTRY_FLAG_IS_REAL | INDI_ENTRY_FLAG_IS_DOUBLED; + case TYPE_FLOAT: + return INDI_ENTRY_FLAG_IS_REAL; + case TYPE_STRING: + case TYPE_UCHAR: + SetUserError(ERR_INVALID_PARAMETER); + break; + default: + SetUserError(ERR_INVALID_PARAMETER); + break; + } + SetUserError(ERR_INVALID_PARAMETER); + return INDI_ENTRY_FLAG_NONE; + } + // Setters. + bool Resize(int _size = 0) { return _size > 0 ? ArrayResize(values, _size) > 0 : true; } + // Value flag methods for bitwise operations. + bool CheckFlag(INDICATOR_ENTRY_FLAGS _prop) { return CheckFlags(_prop); } + bool CheckFlags(unsigned short _flags) { return (flags & _flags) != 0; } + bool CheckFlagsAll(unsigned short _flags) { return (flags & _flags) == _flags; } + void AddFlags(unsigned short _flags) { flags |= _flags; } + void RemoveFlags(unsigned short _flags) { flags &= ~_flags; } + void SetFlag(INDICATOR_ENTRY_FLAGS _flag, bool _value) { + if (_value) { + AddFlags(_flag); + } else { + RemoveFlags(_flag); + } + } + void SetFlags(unsigned short _flags) { flags = _flags; } + unsigned short GetFlags() { return flags; } + // Converters. + // State checkers. + bool IsValid() { return CheckFlags(INDI_ENTRY_FLAG_IS_VALID); } + // Serializers. + void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) { + ArrayResize(values, _n1); + for (int i = 0; i < _n1; ++i) { + values[i] = (int)1; + } + } + SerializerNodeType Serialize(Serializer &_s); + template + string ToCSV() { + int _asize = ArraySize(values); + string _result = ""; + for (int i = 0; i < _asize; i++) { + _result += StringFormat("%s%s", (string)values[i].Get(), i < _asize ? "," : ""); + } + return _result; + } + template + string ToString() { + return ToCSV(); + } +}; diff --git a/IndicatorData.struct.serialize.h b/IndicatorData.struct.serialize.h new file mode 100644 index 000000000..87020224e --- /dev/null +++ b/IndicatorData.struct.serialize.h @@ -0,0 +1,97 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Includes IndicatorData's struct serializers. + */ + +#include "Serializer.mqh" + +// Forward class declaration. +class Serializer; + +/* Method to serialize IndicatorDataEntry structure. */ +SerializerNodeType IndicatorDataEntry::Serialize(Serializer &_s) { + int _asize = ArraySize(values); + _s.Pass(THIS_REF, "datetime", timestamp, SERIALIZER_FIELD_FLAG_DYNAMIC); + _s.Pass(THIS_REF, "flags", flags, SERIALIZER_FIELD_FLAG_DYNAMIC); + for (int i = 0; i < _asize; i++) { + // _s.Pass(THIS_REF, (string)i, values[i], SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); // Can + // this work? _s.Pass(THIS_REF, (string)i, GetEntry(i), SERIALIZER_FIELD_FLAG_DYNAMIC | + // SERIALIZER_FIELD_FLAG_FEATURE); // Can this work? + + switch (values[i].GetDataType()) { + case TYPE_DOUBLE: + _s.Pass(THIS_REF, (string)i, values[i].value.vdbl, + SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); + break; + case TYPE_FLOAT: + _s.Pass(THIS_REF, (string)i, values[i].value.vflt, + SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); + break; + case TYPE_INT: + case TYPE_UINT: + if (CheckFlags(INDI_ENTRY_FLAG_IS_BITWISE)) { + // Split for each bit and pass 0 or 1. + for (int j = 0; j < sizeof(int) * 8; ++j) { + int _value = (values[i].value.vint & (1 << j)) != 0; + _s.Pass(THIS_REF, StringFormat("%d@%d", i, j), _value, SERIALIZER_FIELD_FLAG_FEATURE); + } + } else { + _s.Pass(THIS_REF, (string)i, values[i].value.vint, + SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); + } + break; + case TYPE_LONG: + case TYPE_ULONG: + if (CheckFlags(INDI_ENTRY_FLAG_IS_BITWISE)) { + // Split for each bit and pass 0 or 1. + /* @fixme: j, j already defined. + for (int j = 0; j < sizeof(int) * 8; ++j) { + int _value = (values[i].vlong & (1 << j)) != 0; + _s.Pass(THIS_REF, StringFormat("%d@%d", i, j), _value, SERIALIZER_FIELD_FLAG_FEATURE); + } + */ + SetUserError(ERR_INVALID_PARAMETER); + } else { + _s.Pass(THIS_REF, (string)i, values[i].value.vlong, + SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE); + } + break; + default: + SetUserError(ERR_INVALID_PARAMETER); + break; + } + } + return SerializerNodeObject; +} + +/* Method to serialize IndicatorDataEntry's IndicatorDataEntryValue union. */ +SerializerNodeType IndicatorDataEntryValue::Serialize(Serializer &_s) { + _s.Pass(THIS_REF, "flags", flags); + _s.Pass(THIS_REF, "vdbl", value.vdbl); + _s.Pass(THIS_REF, "vflt", value.vflt); + _s.Pass(THIS_REF, "vint", value.vint); + _s.Pass(THIS_REF, "vlong", value.vlong); + return SerializerNodeObject; +}; diff --git a/Indicator.struct.signal.h b/IndicatorData.struct.signal.h similarity index 100% rename from Indicator.struct.signal.h rename to IndicatorData.struct.signal.h diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 3171251f7..5e64e4bea 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -52,7 +52,7 @@ class Indi_Candle : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Candle(CandleParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Candle(CandleParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CANDLE, _tf, _shift){}; diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index dc5bdc958..e0b0e1322 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -51,7 +51,7 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Pattern(IndiPatternParams& _p, IndicatorBase* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pattern(IndiPatternParams& _p, IndicatorData* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PATTERN, _tf, _shift){}; diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 1ce0404d3..820194f95 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -59,7 +59,7 @@ class Indi_AC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AC(IndiACParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AC(IndiACParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift){}; /** @@ -70,7 +70,7 @@ class Indi_AC : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iac */ static double iAC(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iAC(_symbol, _tf, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index 172eed9f5..9254326f1 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -53,7 +53,7 @@ class Indi_AD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AD(IndiADParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AD(IndiADParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AD, _tf, _shift) { iparams.SetTf(_tf); }; @@ -66,7 +66,7 @@ class Indi_AD : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iad */ static double iAD(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iAD(_symbol, _tf, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 1a3883d14..4aeb85518 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -66,7 +66,7 @@ class Indi_ADX : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ADX(IndiADXParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ADX(IndiADXParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) {} /** @@ -80,7 +80,7 @@ class Indi_ADX : public IndicatorTickOrCandleSource { ENUM_APPLIED_PRICE _applied_price, // (MT5): not used int _mode = LINE_MAIN_ADX, // (MT4/MT5): 0 - MODE_MAIN/MAIN_LINE, 1 - // MODE_PLUSDI/PLUSDI_LINE, 2 - MODE_MINUSDI/MINUSDI_LINE - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iADX(_symbol, _tf, _period, _applied_price, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index b5b11d152..505ce6abd 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -60,7 +60,7 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ADXW(IndiADXWParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ADXW(IndiADXWParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_ADXW(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADXW, _tf, _shift){}; @@ -68,7 +68,7 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { * Built-in version of ADX Wilder. */ static double iADXWilder(string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _mode = LINE_MAIN_ADX, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iADXWilder(_symbol, _tf, _ma_period), _mode, _shift); #else @@ -106,8 +106,8 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { /** * On-indicator version of ADX Wilder. */ - static double iADXWilderOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iADXWilderOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_ADXW_ON_" + _indi.GetFullName(), _period)); return iADXWilderOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _mode, _shift, _cache); diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index e72de2fdc..506318a04 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -69,7 +69,7 @@ class Indi_AMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AMA(IndiAMAParams &_p, IndicatorBase *_indi_src = NULL, int _indi_mode = 0) + Indi_AMA(IndiAMAParams &_p, IndicatorData *_indi_src = NULL, int _indi_mode = 0) : IndicatorTickOrCandleSource(_p, _indi_src, _indi_mode) { iparams.SetIndicatorType(INDI_AMA); }; @@ -80,7 +80,7 @@ class Indi_AMA : public IndicatorTickOrCandleSource { */ static double iAMA(string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN( ::iAMA(_symbol, _tf, _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, _ap), _mode, _shift); @@ -118,9 +118,9 @@ class Indi_AMA : public IndicatorTickOrCandleSource { /** * On-indicator version of AMA. */ - static double iAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, + static double iAMAOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ama_period, int _fast_ema_period, int _slow_ema_period, int _ama_shift, ENUM_APPLIED_PRICE _ap, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS_SPECIFIC( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_AMA_ON_" + _indi.GetFullName(), _ama_period, _fast_ema_period, _slow_ema_period, _ama_shift, @@ -258,7 +258,7 @@ class Indi_AMA : public IndicatorTickOrCandleSource { * Called if data source is requested, but wasn't yet set. May be used to initialize indicators that must operate on * some data source. */ - virtual IndicatorBase *OnDataSourceRequest() { return DataSourceRequestReturnDefault(GetAppliedPrice()); } + virtual IndicatorData *OnDataSourceRequest() { return DataSourceRequestReturnDefault(GetAppliedPrice()); } /* Getters */ diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index 91b8e457c..9786aed4d 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -56,7 +56,7 @@ class Indi_AO : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AO(IndiAOParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AO(IndiAOParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift){}; /** @@ -67,7 +67,7 @@ class Indi_AO : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iao */ static double iAO(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, int _mode = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ // Note: In MQL4 _mode is not supported. return ::iAO(_symbol, _tf, _shift); diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index cccfc3a2a..a0c578e96 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -51,14 +51,14 @@ class Indi_ASI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ASI(IndiASIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ASI(IndiASIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift){}; /** * Built-in version of ASI. */ static double iASI(string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, Util::MakeKey("Indi_ASI", _mpc)); return iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mpc, _mode, _shift, _cache); } @@ -87,8 +87,8 @@ class Indi_ASI : public IndicatorTickOrCandleSource { /** * On-indicator version of ASI. */ - static double iASIOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + static double iASIOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, double _mpc, int _mode = 0, + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_ASI_ON_" + _indi.GetFullName(), _mpc)); return iASIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mpc, _mode, _shift, _cache); diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index 6ddcbd8bc..e3c8f9e69 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -57,7 +57,7 @@ class Indi_ATR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ATR(IndiATRParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ATR(IndiATRParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ATR, _tf, _shift){}; /** @@ -68,7 +68,7 @@ class Indi_ATR : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iatr */ static double iATR(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iATR(_symbol, _tf, _period, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index af6799596..4908498ee 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -100,7 +100,7 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Alligator(IndiAlligatorParams &_p, IndicatorBase *_indi_src = NULL) + Indi_Alligator(IndiAlligatorParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift){}; @@ -126,7 +126,7 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { static double iAlligator(string _symbol, ENUM_TIMEFRAMES _tf, int _jaw_period, int _jaw_shift, int _teeth_period, int _teeth_shift, int _lips_period, int _lips_shift, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_PRICE _applied_price, ENUM_ALLIGATOR_LINE _mode, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iAlligator(_symbol, _tf, _jaw_period, _jaw_shift, _teeth_period, _teeth_shift, _lips_period, _lips_shift, _ma_method, _applied_price, _mode, _shift); diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index 28d43b785..ec4688adc 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -57,7 +57,7 @@ class Indi_AppliedPrice : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_BWMFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BWMFI, _tf, _shift) {} @@ -79,7 +79,7 @@ class Indi_BWMFI : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/ibwmfi */ static double iBWMFI(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, - ENUM_BWMFI_BUFFER _mode = BWMFI_BUFFER, IndicatorBase *_obj = NULL) { + ENUM_BWMFI_BUFFER _mode = BWMFI_BUFFER, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iBWMFI(_symbol, _tf, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 5699beba3..5368be61e 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -40,8 +40,8 @@ enum ENUM_INDI_BWZT_MODE { // Structs. struct IndiBWZTParams : IndicatorParams { - Ref indi_ac; - Ref indi_ao; + Ref indi_ac; + Ref indi_ao; unsigned int period; unsigned int second_period; unsigned int sum_period; @@ -67,14 +67,14 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_BWZT(IndiBWZTParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_BWZT(IndiBWZTParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_BWZT(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BWZT, _tf, _shift){}; /** * Built-in version of BWZT. */ - static double iBWZT(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iBWZT(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_BWZT"); Indi_AC *_indi_ac = Indi_AC::GetCached(_symbol, _tf); @@ -110,8 +110,8 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { /** * On-indicator version of BWZT. */ - static double iBWZTOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode, int _shift, - IndicatorBase *_obj) { + static double iBWZTOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode, int _shift, + IndicatorData *_obj) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_BWZT_ON_" + _indi.GetFullName())); @@ -124,7 +124,7 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { /** * Provides built-in indicators whose can be used as data source. */ - virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { + virtual IndicatorData *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { switch (_id) { case INDI_AC: return iparams.indi_ac.Ptr(); @@ -142,7 +142,7 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { ValueStorage &ExtHBuffer, ValueStorage &ExtLBuffer, ValueStorage &ExtCBuffer, ValueStorage &ExtColorBuffer, ValueStorage &ExtAOBuffer, ValueStorage &ExtACBuffer, int DATA_LIMIT, - IndicatorBase *ExtACHandle, IndicatorBase *ExtAOHandle) { + IndicatorData *ExtACHandle, IndicatorData *ExtAOHandle) { if (rates_total < DATA_LIMIT) return (0); // Not all data may be calculated. int calculated = BarsCalculated(ExtACHandle); diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index 56b4099fb..002a40d08 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -91,7 +91,7 @@ class Indi_Bands : public IndicatorTickSource { /** * Class constructor. */ - Indi_Bands(IndiBandsParams &_p, IndicatorBase *_indi_src = NULL, int _mode = 0) + Indi_Bands(IndiBandsParams &_p, IndicatorData *_indi_src = NULL, int _mode = 0) : IndicatorTickSource(_p, _indi_src, _mode) {} Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_BANDS, _tf, _shift) {} @@ -104,7 +104,7 @@ class Indi_Bands : public IndicatorTickSource { */ static double iBands(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, double _deviation, int _bands_shift, ENUM_APPLIED_PRICE _applied_price, ENUM_BANDS_LINE _mode = BAND_BASE, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iBands(_symbol, _tf, _period, _deviation, _bands_shift, _applied_price, _mode, _shift); #else // __MQL5__ @@ -141,7 +141,7 @@ class Indi_Bands : public IndicatorTickSource { * * When _applied_price is set to -1, method will */ - static double iBandsOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, + static double iBandsOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, double _deviation, int _bands_shift, ENUM_BANDS_LINE _mode, // (MT4/MT5): 0 - MODE_MAIN/BASE_LINE, 1 - // MODE_UPPER/UPPER_BAND, 2 - MODE_LOWER/LOWER_BAND @@ -271,7 +271,7 @@ class Indi_Bands : public IndicatorTickSource { /** * Provides built-in indicators whose can be used as data source. */ - virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) { + virtual IndicatorData *FetchDataSource(ENUM_INDICATOR_TYPE _id) { if (_id == INDI_BANDS) { IndiBandsParams bands_params(); return new Indi_Bands(bands_params); @@ -295,7 +295,7 @@ class Indi_Bands : public IndicatorTickSource { return new Indi_StdDev(stddev_params); } - return IndicatorBase::FetchDataSource(_id); + return IndicatorData::FetchDataSource(_id); } /* Getters */ diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index 5ba1562a7..9d368ddbd 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -56,7 +56,7 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorBase *_indi_src = NULL) + Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BEARS, _tf, _shift) {} @@ -70,7 +70,7 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource */ static double iBearsPower(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, ENUM_APPLIED_PRICE _applied_price, // (MT5): not used - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iBearsPower(_symbol, _tf, _period, _applied_price, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index d1d0491fb..b3ba6ce1d 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -56,7 +56,7 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorBase *_indi_src = NULL) + Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BULLS, _tf, _shift) {} @@ -70,7 +70,7 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource */ static double iBullsPower(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, ENUM_APPLIED_PRICE _applied_price, // (MT5): not used - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iBullsPower(_symbol, _tf, _period, _applied_price, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index 43879b492..7e28d50db 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -63,7 +63,7 @@ class Indi_CCI : public IndicatorTickSource { /** * Class constructor. */ - Indi_CCI(IndiCCIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_CCI(IndiCCIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_CCI, _tf, _shift) {} /** @@ -74,7 +74,7 @@ class Indi_CCI : public IndicatorTickSource { * - https://www.mql5.com/en/docs/indicators/icci */ static double iCCI(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, ENUM_APPLIED_PRICE _applied_price, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iCCI(_symbol, _tf, _period, _applied_price, _shift); #else // __MQL5__ @@ -82,7 +82,7 @@ class Indi_CCI : public IndicatorTickSource { #endif } - static double iCCIOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, + static double iCCIOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, int _mode, int _shift = 0) { _indi.ValidateDataSourceMode(_mode); diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index 5366e2651..673e6da66 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -59,7 +59,7 @@ class Indi_CHO : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHO(IndiCHOParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHO(IndiCHOParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN, _tf, _shift){}; @@ -68,7 +68,7 @@ class Indi_CHO : public IndicatorTickOrCandleSource { */ static double iChaikin(string _symbol, ENUM_TIMEFRAMES _tf, int _fast_ma_period, int _slow_ma_period, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_VOLUME _av, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iChaikin(_symbol, _tf, _fast_ma_period, _slow_ma_period, _ma_method, _av), _mode, _shift); @@ -106,9 +106,9 @@ class Indi_CHO : public IndicatorTickOrCandleSource { /** * On-indicator version of Chaikin Oscillator. */ - static double iChaikinOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _fast_ma_period, + static double iChaikinOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _fast_ma_period, int _slow_ma_period, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_VOLUME _av, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_CHO_ON_" + _indi.GetFullName(), _fast_ma_period, _slow_ma_period, (int)_ma_method, diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 145a03f59..3eb6aabd7 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -60,7 +60,7 @@ class Indi_CHV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHV(IndiCHVParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHV(IndiCHVParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN_V, _tf, _shift){}; @@ -68,7 +68,7 @@ class Indi_CHV : public IndicatorTickOrCandleSource { * Built-in version of Chaikin Volatility. */ static double iCHV(string _symbol, ENUM_TIMEFRAMES _tf, int _smooth_period, int _chv_period, - ENUM_CHV_SMOOTH_METHOD _smooth_method, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + ENUM_CHV_SMOOTH_METHOD _smooth_method, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG( _symbol, _tf, Util::MakeKey("Indi_CHV", _smooth_period, _chv_period, _smooth_method)); return iCHVOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _smooth_period, _chv_period, _smooth_method, _mode, @@ -103,9 +103,9 @@ class Indi_CHV : public IndicatorTickOrCandleSource { /** * On-indicator version of Chaikin Volatility. */ - static double iCHVOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _smooth_period, + static double iCHVOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _smooth_period, int _chv_period, ENUM_CHV_SMOOTH_METHOD _smooth_method, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_CHV_ON_" + _indi.GetFullName(), _smooth_period, _chv_period, _smooth_method)); diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index 7927d1fe2..8fc00a3f8 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -47,7 +47,7 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ColorBars(IndiColorBarsParams &_p, IndicatorBase *_indi_src = NULL) + Indi_ColorBars(IndiColorBarsParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_BARS, _tf, _shift){}; @@ -56,7 +56,7 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { * "Built-in" version of Color Bars. */ static double iColorBars(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_ColorBars"); return iColorBarsOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); } @@ -86,8 +86,8 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { /** * On-indicator version of Color Bars. */ - static double iColorBarsOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + static double iColorBarsOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_ColorBars_ON_" + _indi.GetFullName())); return iColorBarsOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 9348b8095..87ced8ae1 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -47,7 +47,7 @@ class Indi_ColorCandlesDaily : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ColorLine(IndiColorLineParams &_p, IndicatorBase *_indi_src = NULL) + Indi_ColorLine(IndiColorLineParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_LINE, _tf, _shift){}; @@ -59,7 +59,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { * "Built-in" version of Color Line. */ static double iColorLine(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_ColorLine"); Indi_MA *_indi_ma = Indi_MA::GetCached(_symbol, _tf, 10, 0, MODE_EMA, PRICE_CLOSE); @@ -71,7 +71,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { * Calculates Color Line on the array of values. */ static double iColorLineOnArray(INDICATOR_CALCULATE_PARAMS_LONG, int _mode, int _shift, - IndicatorCalculateCache *_cache, IndicatorBase *_indi_ma, + IndicatorCalculateCache *_cache, IndicatorData *_indi_ma, bool _recalculate = false) { _cache.SetPriceBuffer(_open, _high, _low, _close); @@ -92,8 +92,8 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { /** * On-indicator version of Color Line. */ - static double iColorLineOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + static double iColorLineOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_ColorLine_ON_" + _indi.GetFullName())); @@ -105,7 +105,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { /** * Provides built-in indicators whose can be used as data source. */ - virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { + virtual IndicatorData *FetchDataSource(ENUM_INDICATOR_TYPE _id) override { switch (_id) { case INDI_MA: return iparams.indi_ma; @@ -117,7 +117,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { * OnCalculate() method for Color Line indicator. */ static int Calculate(INDICATOR_CALCULATE_METHOD_PARAMS_LONG, ValueStorage &ExtColorLineBuffer, - ValueStorage &ExtColorsBuffer, IndicatorBase *ExtMAHandle) { + ValueStorage &ExtColorsBuffer, IndicatorData *ExtMAHandle) { static int ticks = 0, modified = 0; // Check data. int i, calculated = BarsCalculated(ExtMAHandle); diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index e172c2b69..e55cd4e6e 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -59,7 +59,7 @@ class Indi_CustomMovingAverage : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMA, _tf, _shift) {} @@ -79,7 +79,7 @@ class Indi_DEMA : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/IDEMA */ static double iDEMA(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, unsigned int _ma_shift, - ENUM_APPLIED_PRICE _applied_price, int _shift = 0, int _mode = 0, IndicatorBase *_obj = NULL) { + ENUM_APPLIED_PRICE _applied_price, int _shift = 0, int _mode = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ int _handle = Object::IsValid(_obj) ? _obj.Get(IndicatorState::INDICATOR_STATE_PROP_HANDLE) : NULL; double _res[]; @@ -113,7 +113,7 @@ class Indi_DEMA : public IndicatorTickOrCandleSource { #endif } - static double iDEMAOnIndicatorSlow(IndicatorCalculateCache *cache, IndicatorBase *_indi, int indi_mode, + static double iDEMAOnIndicatorSlow(IndicatorCalculateCache *cache, IndicatorData *_indi, int indi_mode, unsigned int ma_period, unsigned int ma_shift, int shift) { return iDEMAOnArray(_indi.GetValueStorage(indi_mode), 0, ma_period, ma_shift, shift, cache); } @@ -148,8 +148,8 @@ class Indi_DEMA : public IndicatorTickOrCandleSource { /** * On-indicator version of DEMA. */ - static double iDEMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, int _ma_shift, - ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iDEMAOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, int _ma_shift, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, (int)_ap, Util::MakeKey("Indi_CHV_ON_" + _indi.GetFullName(), _period, _ma_shift)); return iDEMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _period, _ma_shift, _mode, _shift, _cache); diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index 2e67aa4ea..b62b6516d 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -55,7 +55,7 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMARKER, _tf, _shift) {} @@ -67,7 +67,7 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/idemarker */ static double iDeMarker(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iDeMarker(_symbol, _tf, _period, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index 9fd756862..4b3f8b57b 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -58,7 +58,7 @@ class Indi_Demo : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Demo(IndiDemoParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Demo(IndiDemoParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMO, _tf, _shift){}; @@ -66,7 +66,7 @@ class Indi_Demo : public IndicatorTickOrCandleSource { * Returns the indicator value. */ static double iDemo(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { return 0.1 + (0.1 * _obj.GetBarIndex()); } diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index 3f78bdddd..c35f6d295 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -53,7 +53,7 @@ class Indi_DetrendedPrice : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Drawer(const IndiDrawerParams &_p, IndicatorBase *_indi_src = NULL) + Indi_Drawer(const IndiDrawerParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src), redis(true) { Init(); } @@ -150,14 +150,14 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/irsi */ static double iDrawer(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { return 1.0; } /** * Performs drawing on data from other indicator. */ - static double iDrawerOnIndicator(IndicatorBase *_indi, Indi_Drawer *_obj, string _symbol = NULL, + static double iDrawerOnIndicator(IndicatorData *_indi, Indi_Drawer *_obj, string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) { // This method is not yet implemented. return 1.0; @@ -173,7 +173,7 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { /** * Returns the indicator's value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); switch (iparams.idstype) { @@ -217,4 +217,5 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { istate.is_changed = true; iparams.applied_price = _applied_price; } + }; diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index ecede2db4..87624125b 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -81,7 +81,7 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorBase *_indi_src = NULL) + Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ENVELOPES, _tf, _shift) {} @@ -97,7 +97,7 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { int _ma_shift, ENUM_APPLIED_PRICE _ap, double _deviation, int _mode, // (MT4 _mode): 0 - MODE_MAIN, 1 - MODE_UPPER, 2 - MODE_LOWER; (MT5 _mode): 0 - // UPPER_LINE, 1 - LOWER_LINE - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iEnvelopes(_symbol, _tf, _ma_period, _ma_method, _ma_shift, _ap, _deviation, _mode, _shift); #else // __MQL5__ @@ -138,7 +138,7 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { #endif } - static double iEnvelopesOnIndicator(IndicatorCalculateCache *_cache, IndicatorBase *_indi, string _symbol, + static double iEnvelopesOnIndicator(IndicatorCalculateCache *_cache, IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, ENUM_MA_METHOD _ma_method, // (MT4/MT5): MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA int _indi_mode, // Source indicator's mode index. May be -1 to use first buffer diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 661bdc6a4..96a961c7c 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -71,7 +71,7 @@ class Indi_Force : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Force(IndiForceParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Force(IndiForceParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FORCE, _tf, _shift) {} @@ -83,7 +83,7 @@ class Indi_Force : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iforce */ static double iForce(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, ENUM_MA_METHOD _ma_method, - ENUM_APPLIED_PRICE _applied_price, int _shift = 0, IndicatorBase *_obj = NULL) { + ENUM_APPLIED_PRICE _applied_price, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iForce(_symbol, _tf, _period, _ma_method, _applied_price, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index a0c69a60c..558c643e9 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -55,7 +55,7 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FRAMA, _tf, _shift){}; @@ -63,7 +63,7 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { * Built-in version of FrAMA. */ static double iFrAMA(string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iFrAMA(_symbol, _tf, _ma_period, _ma_shift, _ap), _mode, _shift); #else @@ -98,9 +98,9 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { /** * On-indicator version of FrAMA. */ - static double iFrAMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + static double iFrAMAOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_AMA_ON_" + _indi.GetFullName(), _ma_period, _ma_shift, (int)_ap)); return iFrAMAOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _ma_period, _ma_shift, _ap, _mode, _shift, _cache); diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 33dbce3b1..01205d3de 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -53,7 +53,7 @@ class Indi_Fractals : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Fractals(IndiFractalsParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Fractals(IndiFractalsParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Fractals(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FRACTALS, _tf, _shift) {} @@ -67,7 +67,7 @@ class Indi_Fractals : public IndicatorTickOrCandleSource { static double iFractals(string _symbol, ENUM_TIMEFRAMES _tf, ENUM_LO_UP_LINE _mode, // (MT4 _mode): 1 - MODE_UPPER, 2 - MODE_LOWER int _shift = 0, // (MT5 _mode): 0 - UPPER_LINE, 1 - LOWER_LINE - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iFractals(_symbol, _tf, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index f87e8fc5a..a82905673 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -108,7 +108,7 @@ class Indi_Gator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Gator(IndiGatorParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Gator(IndiGatorParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Gator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_GATOR, _tf, _shift) {} @@ -133,7 +133,7 @@ class Indi_Gator : public IndicatorTickOrCandleSource { static double iGator(string _symbol, ENUM_TIMEFRAMES _tf, int _jaw_period, int _jaw_shift, int _teeth_period, int _teeth_shift, int _lips_period, int _lips_shift, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_PRICE _applied_price, ENUM_GATOR_HISTOGRAM _mode, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iGator(_symbol, _tf, _jaw_period, _jaw_shift, _teeth_period, _teeth_shift, _lips_period, _lips_shift, _ma_method, _applied_price, _mode, _shift); diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index e3c3e33bc..ed6581801 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -73,7 +73,7 @@ class Indi_HeikenAshi : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_HeikenAshi(IndiHeikenAshiParams &_p, IndicatorBase *_indi_src = NULL) + Indi_HeikenAshi(IndiHeikenAshiParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_HeikenAshi(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_HEIKENASHI, _tf, _shift) {} @@ -82,7 +82,7 @@ class Indi_HeikenAshi : public IndicatorTickOrCandleSource * Returns value for iHeikenAshi indicator. */ static double iCustomLegacyHeikenAshi(string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _mode, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ // Low and High prices could be in reverse order when using MT4's built-in indicator, so we need to retrieve both // and return correct one. @@ -161,8 +161,8 @@ class Indi_HeikenAshi : public IndicatorTickOrCandleSource /** * On-indicator version of Heiken Ashi. */ - static double iHeikenAshiOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + static double iHeikenAshiOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_HeikenAshi_ON_" + _indi.GetFullName())); return iHeikenAshiOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index e87290e9e..943c0393c 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -91,7 +91,7 @@ class Indi_Ichimoku : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Ichimoku(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ICHIMOKU, _tf, _shift) {} @@ -107,7 +107,7 @@ class Indi_Ichimoku : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iichimoku */ static double iIchimoku(string _symbol, ENUM_TIMEFRAMES _tf, int _tenkan_sen, int _kijun_sen, int _senkou_span_b, - int _mode, int _shift = 0, IndicatorBase *_obj = NULL) { + int _mode, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iIchimoku(_symbol, _tf, _tenkan_sen, _kijun_sen, _senkou_span_b, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index 5fc584d03..667d16397 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -99,7 +99,7 @@ class Indi_Killzones : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Killzones(IndiKillzonesParams &_p, IndicatorBase *_indi_src = NULL) + Indi_Killzones(IndiKillzonesParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_KILLZONES, _tf, _shift) {} diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 32aecbcff..8c56dbfdf 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -79,7 +79,7 @@ class Indi_MA : public IndicatorTickSource { /** * Class constructor. */ - Indi_MA(IndiMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_MA(IndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_MA, _tf, _shift) {} /** @@ -91,7 +91,7 @@ class Indi_MA : public IndicatorTickSource { */ static double iMA(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _ma_period, unsigned int _ma_shift, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_PRICE _applied_array, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_array, _shift); #else // __MQL5__ @@ -126,7 +126,7 @@ class Indi_MA : public IndicatorTickSource { /** * Calculates MA on another indicator. */ - static double iMAOnIndicator(IndicatorCalculateCache *cache, IndicatorBase *_indi, int indi_mode, + static double iMAOnIndicator(IndicatorCalculateCache *cache, IndicatorData *_indi, int indi_mode, string symbol, ENUM_TIMEFRAMES tf, unsigned int ma_period, unsigned int ma_shift, ENUM_MA_METHOD ma_method, // (MT4/MT5): MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA int shift = 0) { diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index 445c9d8dd..08d760125 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -64,7 +64,7 @@ class Indi_MACD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MACD(IndiMACDParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MACD(IndiMACDParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MACD, _tf, _shift) {} @@ -79,7 +79,7 @@ class Indi_MACD : public IndicatorTickOrCandleSource { string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _ema_fast_period, unsigned int _ema_slow_period, unsigned int _signal_period, ENUM_APPLIED_PRICE _applied_price, ENUM_SIGNAL_LINE _mode = LINE_MAIN, // (MT4/MT5 _mode): 0 - MODE_MAIN/MAIN_LINE, 1 - MODE_SIGNAL/SIGNAL_LINE - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iMACD(_symbol, _tf, _ema_fast_period, _ema_slow_period, _signal_period, _applied_price, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index f2ad316b1..7e0a70d2c 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -56,7 +56,7 @@ class Indi_MFI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MFI(IndiMFIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MFI(IndiMFIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MFI, _tf, _shift) {} /** @@ -67,7 +67,7 @@ class Indi_MFI : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/imfi */ static double iMFI(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iMFI(_symbol, _tf, _period, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index b541f236e..6ee2afb9e 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -55,7 +55,7 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MassIndex(IndiMassIndexParams &_p, IndicatorBase *_indi_src = NULL) + Indi_MassIndex(IndiMassIndexParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MASS_INDEX, _tf, _shift){}; @@ -64,7 +64,7 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { * Built-in version of Mass Index. */ static double iMI(string _symbol, ENUM_TIMEFRAMES _tf, int _period, int _second_period, int _sum_period, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG( _symbol, _tf, Util::MakeKey("Indi_MassIndex", _period, _second_period, _sum_period)); return iMIOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _second_period, _sum_period, _mode, _shift, @@ -96,9 +96,9 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { /** * On-indicator version of Mass Index. */ - static double iMIOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + static double iMIOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, int _second_period, int _sum_period, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_MassIndex_ON_" + _indi.GetFullName(), _period, _second_period, _sum_period)); diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 7dc6d01ea..8d69ba91f 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -66,7 +66,7 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Momentum(IndiMomentumParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Momentum(IndiMomentumParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MOMENTUM, _tf, _shift) {} @@ -78,7 +78,7 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/imomentum */ static double iMomentum(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, ENUM_APPLIED_PRICE _ap, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iMomentum(_symbol, _tf, _period, _ap, _shift); #else // __MQL5__ @@ -110,7 +110,7 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { #endif } - static double iMomentumOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, + static double iMomentumOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _period, int _mode, int _shift = 0) { double _indi_value_buffer[]; IndicatorDataEntry _entry(_indi.GetModeCount()); diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index dddc611e3..abc67491f 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -67,7 +67,7 @@ class Indi_OBV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OBV(IndiOBVParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OBV(IndiOBVParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OBV, _tf, _shift) {} /** @@ -83,7 +83,7 @@ class Indi_OBV : public IndicatorTickOrCandleSource { #else ENUM_APPLIED_VOLUME _applied = VOLUME_TICK, // MT5 only. #endif - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iOBV(_symbol, _tf, _applied, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index 22520384c..4ddfbf98f 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -63,7 +63,7 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OsMA(IndiOsMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OsMA(IndiOsMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OSMA, _tf, _shift) {} @@ -76,7 +76,7 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { */ static double iOsMA(string _symbol, ENUM_TIMEFRAMES _tf, int _ema_fast_period, int _ema_slow_period, int _signal_period, ENUM_APPLIED_PRICE _applied_price, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iOsMA(_symbol, _tf, _ema_fast_period, _ema_slow_period, _signal_period, _applied_price, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 75a737974..358d657a3 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -49,7 +49,7 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Pivot(IndiPivotParams& _p, IndicatorBase* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pivot(IndiPivotParams& _p, IndicatorData* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PIVOT, _tf, _shift) { iparams.tf = _tf; diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index 97fbe41d2..cefbbcaa3 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -50,7 +50,7 @@ class Indi_PriceChannel : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RS(IndiRSParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) { Init(); }; + Indi_RS(IndiRSParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) { Init(); }; Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RS, _tf, _shift) { Init(); }; diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index f573ffad3..d1f8fd823 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -96,7 +96,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RSI(IndiRSIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RSI(IndiRSIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RSI, _tf, _shift) {} /** @@ -107,7 +107,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/irsi */ static double iRSI(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, unsigned int _period = 14, - ENUM_APPLIED_PRICE _applied_price = PRICE_CLOSE, int _shift = 0, IndicatorBase *_obj = NULL) { + ENUM_APPLIED_PRICE _applied_price = PRICE_CLOSE, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iRSI(_symbol, _tf, _period, _applied_price, _shift); #else // __MQL5__ @@ -119,7 +119,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { * Calculates non-SMMA version of RSI on another indicator (uses iRSIOnArray). */ template - static double iRSIOnArrayOnIndicator(IndicatorBase *_indi, string _symbol = NULL, + static double iRSIOnArrayOnIndicator(IndicatorData *_indi, string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, unsigned int _period = 14, ENUM_APPLIED_PRICE _applied_price = PRICE_CLOSE, int _shift = 0, Indi_RSI *_obj = NULL) { @@ -153,7 +153,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { * RSI values. To exactly replicate our RSI numbers, a formula will need at * least 250 data points." */ - static double iRSIOnIndicator(IndicatorBase *_indi, Indi_RSI *_obj, string _symbol = NULL, + static double iRSIOnIndicator(IndicatorData *_indi, Indi_RSI *_obj, string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, unsigned int _period = 14, ENUM_APPLIED_PRICE _applied_price = PRICE_CLOSE, int _shift = 0) { long _bar_time_curr = _obj.GetBarTime(_shift); @@ -314,7 +314,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { /** * Provides built-in indicators whose can be used as data source. */ - virtual IndicatorBase *FetchDataSource(ENUM_INDICATOR_TYPE _id) { + virtual IndicatorData *FetchDataSource(ENUM_INDICATOR_TYPE _id) { if (_id == INDI_BANDS) { IndiBandsParams bands_params; return new Indi_Bands(bands_params); @@ -338,6 +338,6 @@ class Indi_RSI : public IndicatorTickOrCandleSource { return new Indi_StdDev(stddev_params); } - return IndicatorBase::FetchDataSource(_id); + return IndicatorData::FetchDataSource(_id); } }; diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index e19867e8a..f51328fa6 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -55,7 +55,7 @@ class Indi_RVI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RVI(const IndiRVIParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RVI(const IndiRVIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RVI, _tf, _shift) {} /** @@ -68,7 +68,7 @@ class Indi_RVI : public IndicatorTickOrCandleSource { static double iRVI( string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, unsigned int _period = 10, ENUM_SIGNAL_LINE _mode = LINE_MAIN, // (MT4/MT5): 0 - MODE_MAIN/MAIN_LINE, 1 - MODE_SIGNAL/SIGNAL_LINE - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iRVI(_symbol, _tf, _period, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index 2f0d5b061..e179dcf5e 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -52,7 +52,7 @@ class Indi_RateOfChange : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_SAR(IndiSARParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_SAR(IndiSARParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SAR, _tf, _shift) {} /** @@ -67,7 +67,7 @@ class Indi_SAR : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/isar */ static double iSAR(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, double _step = 0.02, - double _max = 0.2, int _shift = 0, IndicatorBase *_obj = NULL) { + double _max = 0.2, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iSAR(_symbol, _tf, _step, _max, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 5effc7dcd..3aae93627 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -78,7 +78,7 @@ class Indi_StdDev : public IndicatorTickSource { /** * Class constructor. */ - Indi_StdDev(IndiStdDevParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_StdDev(IndiStdDevParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_STDDEV, _tf, _shift) {} /** @@ -89,7 +89,7 @@ class Indi_StdDev : public IndicatorTickSource { * - https://www.mql5.com/en/docs/indicators/istddev */ static double iStdDev(string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _ma_shift, ENUM_MA_METHOD _ma_method, - ENUM_APPLIED_PRICE _applied_price, int _shift = 0, IndicatorBase *_obj = NULL) { + ENUM_APPLIED_PRICE _applied_price, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iStdDev(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price, _shift); #else // __MQL5__ @@ -124,7 +124,7 @@ class Indi_StdDev : public IndicatorTickSource { /** * Note that this method operates on current price (set by _applied_price). */ - static double iStdDevOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + static double iStdDevOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _ma_shift, ENUM_APPLIED_PRICE _applied_price, int _shift = 0, Indi_StdDev *_obj = NULL) { double _indi_value_buffer[]; diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index f93c4cbce..2b6a1994a 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -67,7 +67,7 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Stochastic(IndiStochParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Stochastic(IndiStochParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_STOCHASTIC, _tf, _shift) {} @@ -84,7 +84,7 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { ENUM_STO_PRICE _price_field, // (MT4 _price_field): 0 - Low/High, 1 - Close/Close // (MT5 _price_field): STO_LOWHIGH - Low/High, STO_CLOSECLOSE - Close/Close int _mode, // (MT4): 0 - MODE_MAIN/MAIN_LINE, 1 - MODE_SIGNAL/SIGNAL_LINE - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iStochastic(_symbol, _tf, _kperiod, _dperiod, _slowing, _ma_method, _price_field, _mode, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 5954a9804..785d0d956 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -55,7 +55,7 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TEMA(IndiTEMAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TEMA(IndiTEMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TEMA, _tf, _shift){}; @@ -98,9 +98,9 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { /** * On-indicator version of TEMA. */ - static double iTEMAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + static double iTEMAOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_TEMA_ON_" + _indi.GetFullName(), _ma_period, _ma_shift, (int)_ap)); diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index 86caabb0d..e5d521679 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -54,7 +54,7 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TRIX(IndiTRIXParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TRIX(IndiTRIXParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TRIX, _tf, _shift){}; @@ -62,7 +62,7 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { * Built-in version of TriX. */ static double iTriX(string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, ENUM_APPLIED_PRICE _ap, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iTriX(_symbol, _tf, _ma_period, _ap), _mode, _shift); #else @@ -97,8 +97,8 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { /** * On-indicator version of TriX. */ - static double iTriXOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, - ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iTriXOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _ma_period, + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_TriX_ON_" + _indi.GetFullName(), _ma_period, (int)_ap)); return iTriXOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_SHORT, _ma_period, _mode, _shift, _cache); diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index 98a7f9e1f..a6cf9c4b5 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -29,9 +29,9 @@ // Structs. struct IndiUltimateOscillatorParams : IndicatorParams { - Ref indi_atr_fast; - Ref indi_atr_middle; - Ref indi_atr_slow; + Ref indi_atr_fast; + Ref indi_atr_middle; + Ref indi_atr_slow; int fast_period; int middle_period; int slow_period; @@ -67,7 +67,7 @@ class Indi_UltimateOscillator : public IndicatorTickOrCandleSource *_cache, IndicatorBase *_indi_atr_fast, - IndicatorBase *_indi_atr_middle, IndicatorBase *_indi_atr_slow, bool _recalculate = false) { + IndicatorCalculateCache *_cache, IndicatorData *_indi_atr_fast, + IndicatorData *_indi_atr_middle, IndicatorData *_indi_atr_slow, bool _recalculate = false) { _cache.SetPriceBuffer(_open, _high, _low, _close); if (!_cache.HasBuffers()) { @@ -119,9 +119,9 @@ class Indi_UltimateOscillator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VIDYA(IndiVIDYAParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VIDYA(IndiVIDYAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VIDYA, _tf, _shift){}; @@ -66,7 +66,7 @@ class Indi_VIDYA : public IndicatorTickOrCandleSource { * Built-in version of iVIDyA. */ static double iVIDyA(string _symbol, ENUM_TIMEFRAMES _tf, int _cmo_period, int _ema_period, int _ma_shift, - ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iVIDyA(_symbol, _tf, _cmo_period, _ema_period, _ma_shift, _ap), _mode, _shift); #else @@ -102,9 +102,9 @@ class Indi_VIDYA : public IndicatorTickOrCandleSource { /** * On-indicator version of VIDya indicator. */ - static double iVIDyAOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _cmo_period, + static double iVIDyAOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _cmo_period, int _ema_period, int _ma_shift, ENUM_APPLIED_PRICE _ap, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_SHORT_DS( _indi, _symbol, _tf, _ap, Util::MakeKey("Indi_VIDYA_ON_" + _indi.GetFullName(), _cmo_period, _ema_period, _ma_shift, (int)_ap)); diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index cacf2861c..d06dc12fa 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -52,7 +52,7 @@ class Indi_VROC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VROC(IndiVROCParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VROC(IndiVROCParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; @@ -60,7 +60,7 @@ class Indi_VROC : public IndicatorTickOrCandleSource { * Built-in version of VROC. */ static double iVROC(string _symbol, ENUM_TIMEFRAMES _tf, int _period, ENUM_APPLIED_VOLUME _av, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, Util::MakeKey("Indi_VROC", _period, (int)_av)); return iVROCOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _av, _mode, _shift, _cache); } @@ -89,8 +89,8 @@ class Indi_VROC : public IndicatorTickOrCandleSource { /** * On-indicator version of VROC indicator. */ - static double iVROCOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, - ENUM_APPLIED_VOLUME _av, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iVROCOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _period, + ENUM_APPLIED_VOLUME _av, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_VROC_ON_" + _indi.GetFullName(), _period, (int)_av)); return iVROCOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _period, _av, _mode, _shift, _cache); diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index c46671424..9a22469f2 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -51,7 +51,7 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Volumes(IndiVolumesParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Volumes(IndiVolumesParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VOLUMES, _tf, _shift){}; @@ -59,7 +59,7 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { * Built-in version of Volumes. */ static double iVolumes(string _symbol, ENUM_TIMEFRAMES _tf, ENUM_APPLIED_VOLUME _av, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, Util::MakeKey("Indi_Volumes", (int)_av)); return iVolumesOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _av, _mode, _shift, _cache); } @@ -88,8 +88,8 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { /** * On-indicator version of Volumes indicator. */ - static double iVolumesOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_APPLIED_VOLUME _av, - int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iVolumesOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_APPLIED_VOLUME _av, + int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_Volumes_ON_" + _indi.GetFullName(), (int)_av)); return iVolumesOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _av, _mode, _shift, _cache); diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index b202f3535..a4954ae71 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -55,7 +55,7 @@ class Indi_WPR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_WPR(IndiWPRParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_WPR(IndiWPRParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WPR, _tf, _shift) {} /** @@ -66,7 +66,7 @@ class Indi_WPR : public IndicatorTickOrCandleSource { * - https://www.mql5.com/en/docs/indicators/iwpr */ static double iWPR(string _symbol = NULL, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, unsigned int _period = 14, - int _shift = 0, IndicatorBase *_obj = NULL) { + int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL4__ return ::iWPR(_symbol, _tf, _period, _shift); #else // __MQL5__ diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 7e2bf94e4..c46b3c9dc 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -47,7 +47,7 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorBase *_indi_src = NULL) + Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WILLIAMS_AD, _tf, _shift){}; @@ -55,7 +55,7 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource /** * Built-in version of Williams' AD. */ - static double iWAD(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + static double iWAD(string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG(_symbol, _tf, "Indi_WilliamsAD"); return iWADOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); } @@ -84,8 +84,8 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource /** * On-indicator version of Williams' AD. */ - static double iWADOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, - int _shift = 0, IndicatorBase *_obj = NULL) { + static double iWADOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _mode = 0, + int _shift = 0, IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS(_indi, _symbol, _tf, Util::MakeKey("Indi_WilliamsAD_ON_" + _indi.GetFullName())); return iWADOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _mode, _shift, _cache); diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index ec8147ee9..316b8a704 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -63,7 +63,7 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ZigZag(IndiZigZagParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ZigZag(IndiZigZagParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ZIGZAG, _tf, _shift) {} @@ -71,7 +71,7 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { * Returns value for ZigZag indicator. */ static double iCustomZigZag(string _symbol, ENUM_TIMEFRAMES _tf, string _name, int _depth, int _deviation, - int _backstep, ENUM_ZIGZAG_LINE _mode = 0, int _shift = 0, IndicatorBase *_obj = NULL) { + int _backstep, ENUM_ZIGZAG_LINE _mode = 0, int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL5__ int _handle = Object::IsValid(_obj) ? _obj.Get(IndicatorState::INDICATOR_STATE_PROP_HANDLE) : NULL; double _res[]; @@ -139,9 +139,9 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { /** * On-indicator version of ZigZag indicator. */ - static double iZigZagOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _depth, + static double iZigZagOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, int _depth, int _deviation, int _backstep, int _mode = 0, int _shift = 0, - IndicatorBase *_obj = NULL) { + IndicatorData *_obj = NULL) { INDICATOR_CALCULATE_POPULATE_PARAMS_AND_CACHE_LONG_DS( _indi, _symbol, _tf, Util::MakeKey("Indi_ZigZag_ON_" + _indi.GetFullName(), _depth, _deviation, _backstep)); return iZigZagOnArray(INDICATOR_CALCULATE_POPULATED_PARAMS_LONG, _depth, _deviation, _backstep, _mode, _shift, diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index 6e8cf6d9a..013de75f9 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -57,7 +57,7 @@ class Indi_ZigZagColor : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OHLC(IndiOHLCParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_OHLC(IndiOHLCParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_OHLC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index b0cbcc6d3..53700b731 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -51,7 +51,7 @@ class Indi_Price : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Price(PriceIndiParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Price(PriceIndiParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Price(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Special/Indi_Custom.mqh b/Indicators/Special/Indi_Custom.mqh index d35236289..9e6daade7 100644 --- a/Indicators/Special/Indi_Custom.mqh +++ b/Indicators/Special/Indi_Custom.mqh @@ -79,7 +79,7 @@ class Indi_Custom : public Indicator { /** * Class constructor. */ - Indi_Custom(IndiCustomParams &_p, IndicatorBase *_indi_src = NULL) : Indicator(_p, _indi_src) {} + Indi_Custom(IndiCustomParams &_p, IndicatorData *_indi_src = NULL) : Indicator(_p, _indi_src) {} Indi_Custom(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(INDI_CUSTOM, _tf){}; /** diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index 098b4fc3f..80190ab0e 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -87,7 +87,7 @@ class Indi_Math : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Math(IndiMathParams &_p, IndicatorBase *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Math(IndiMathParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SPECIAL_MATH, _tf, _shift){}; @@ -130,7 +130,7 @@ class Indi_Math : public IndicatorTickOrCandleSource { return _value; } - static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_MATH_OP op, + static double iMathOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, ENUM_MATH_OP op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { double _val_1 = _indi.GetValue(_mode_1, _shift_1); @@ -138,7 +138,7 @@ class Indi_Math : public IndicatorTickOrCandleSource { return Math::Op(op, _val_1, _val_2); } - static double iMathOnIndicator(IndicatorBase *_indi, string _symbol, ENUM_TIMEFRAMES _tf, MathCustomOpFunction _op, + static double iMathOnIndicator(IndicatorData *_indi, string _symbol, ENUM_TIMEFRAMES _tf, MathCustomOpFunction _op, unsigned int _mode_1, unsigned int _mode_2, unsigned int _shift_1, unsigned int _shift_2, unsigned int _mode, int _shift, Indi_Math *_obj) { double _val_1 = _indi.GetValue(_mode_1, _shift_1); diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 9f03835b9..2ea365183 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -52,7 +52,7 @@ class Indi_TickMt : public IndicatorTick { /** * Class constructor. */ - Indi_TickMt(IndiTickMtParams &_p, IndicatorBase *_indi_src = NULL) + Indi_TickMt(IndiTickMtParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTick(_p, _indi_src){}; Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} diff --git a/Storage/ValueStorage.indicator.h b/Storage/ValueStorage.indicator.h index e363559b2..928386577 100644 --- a/Storage/ValueStorage.indicator.h +++ b/Storage/ValueStorage.indicator.h @@ -31,7 +31,7 @@ #endif // Forward declarations. -class IndicatorBase; +class IndicatorData; // Includes. #include "ValueStorage.history.h" @@ -42,7 +42,7 @@ class IndicatorBase; template class IndicatorBufferValueStorage : public HistoryValueStorage { // Pointer to indicator to access data from. - IndicatorBase *indicator; + IndicatorData *indicator; // Mode of the target indicator. int mode; @@ -51,7 +51,7 @@ class IndicatorBufferValueStorage : public HistoryValueStorage { /** * Constructor. */ - IndicatorBufferValueStorage(IndicatorBase *_indi, int _mode = 0, bool _is_series = false) + IndicatorBufferValueStorage(IndicatorData *_indi, int _mode = 0, bool _is_series = false) : indicator(_indi), mode(_mode), HistoryValueStorage(_indi.GetSymbol(), _indi.GetTf()) {} /** diff --git a/tests/CompileTest.mq5 b/tests/CompileTest.mq5 index dea9802e4..ef6ceeab7 100644 --- a/tests/CompileTest.mq5 +++ b/tests/CompileTest.mq5 @@ -62,6 +62,7 @@ #include "../ISerializable.h" #include "../Indicator.define.h" #include "../Indicator.mqh" +#include "../IndicatorBase.h" #include "../IndicatorData.mqh" #include "../Inet.mqh" #include "../Log.mqh" diff --git a/tests/DrawIndicatorTest.mq5 b/tests/DrawIndicatorTest.mq5 index 0ec2fc83b..ef1988fc4 100644 --- a/tests/DrawIndicatorTest.mq5 +++ b/tests/DrawIndicatorTest.mq5 @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ @@ -36,7 +36,7 @@ // Global variables. Chart *chart; -Dict indis; +Dict indis; int bar_processed; /** @@ -64,8 +64,8 @@ void OnTick() { if (chart.IsNewBar()) { bar_processed++; - for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { - IndicatorBase *_indi = iter.Value(); + for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { + IndicatorData *_indi = iter.Value(); _indi.OnTick(); IndicatorDataEntry _entry = _indi.GetEntry(); if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY)) && _entry.IsValid()) { @@ -81,7 +81,7 @@ void OnTick() { void OnDeinit(const int reason) { delete chart; - for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { + for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { delete iter.Value(); } } @@ -152,7 +152,7 @@ bool InitIndicators() { */ bool PrintIndicators(string _prefix = "") { ResetLastError(); - for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { + for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { IndicatorBase *_indi = iter.Value(); if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { PrintFormat("%s: %s: %s", _prefix, _indi.GetName(), _indi.ToString()); diff --git a/tests/IndicatorBaseTest.mq4 b/tests/IndicatorBaseTest.mq4 new file mode 100644 index 000000000..167dec35e --- /dev/null +++ b/tests/IndicatorBaseTest.mq4 @@ -0,0 +1,28 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Test functionality of IndicatorBase class. + */ + +// Includes. +#include "IndicatorBaseTest.mq5" diff --git a/tests/IndicatorBaseTest.mq5 b/tests/IndicatorBaseTest.mq5 new file mode 100644 index 000000000..8ca89f936 --- /dev/null +++ b/tests/IndicatorBaseTest.mq5 @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Test functionality of IndicatorBase class. + */ + +// Includes. +#include "../IndicatorBase.h" +#include "../Test.mqh" + +/** + * Implements OnInit(). + */ +int OnInit() { + // @todo + return (INIT_SUCCEEDED); +} diff --git a/tests/IndicatorDataTest.mq4 b/tests/IndicatorDataTest.mq4 index dd6581caa..ec907afe1 100644 --- a/tests/IndicatorDataTest.mq4 +++ b/tests/IndicatorDataTest.mq4 @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ @@ -25,184 +25,4 @@ */ // Includes. -#include "../IndicatorData.mqh" - -// User inputs. -#ifdef __input__ input #endif string __MA_Parameters__ = "-- Settings for the Moving Average indicator --"; // >>> MA <<< -#ifdef __input__ input #endif int MA_Period_Fast = 14; // Period Fast -#ifdef __input__ input #endif int MA_Period_Medium = 20; // Period Medium -#ifdef __input__ input #endif int MA_Period_Slow = 48; // Period Slow -#ifdef __input__ input #endif double MA_Period_Ratio = 1.0; // Period ratio between timeframes (0.5-1.5) -#ifdef __input__ input #endif int MA_Shift = 0; // Shift -#ifdef __input__ input #endif int MA_Shift_Fast = 0; // Shift Fast (+1) -#ifdef __input__ input #endif int MA_Shift_Medium = 0; // Shift Medium (+1) -#ifdef __input__ input #endif int MA_Shift_Slow = 1; // Shift Slow (+1) -#ifdef __input__ input #endif int MA_Shift_Far = 4; // Shift Far (+2) -#ifdef __input__ input #endif ENUM_MA_METHOD MA_Method = 1; // MA Method -#ifdef __input__ input #endif ENUM_APPLIED_PRICE MA_Applied_Price = 3; // Applied Price - -class I_MA : public IndicatorData { - protected: - // Indicator Buffers. - enum ENUM_MA_MODE { - MODE_MA_FAST = 0, - MODE_MA_MEDIUM = 1, - MODE_MA_SLOW = 2, - MAX_OF_ENUM_MA_MODE // Buffers count - }; - - public: - /** - * Class constructor. - */ - void I_MA() : IndicatorData("Custom MA Indicator", MAX_OF_ENUM_MA_MODE) {} - - /** - * Returns the indicator value. - * - * @docs - * - https://docs.mql4.com/indicators/ima - * - https://www.mql5.com/en/docs/indicators/ima - */ - static double iMA(string _symbol, ENUM_TIMEFRAMES _tf, uint _ma_period, int _ma_shift, - ENUM_MA_METHOD _ma_method, // (MT4/MT5): MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA - ENUM_APPLIED_PRICE _applied_price, // (MT4/MT5): PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, - // PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED - int _shift = 0) { -#ifdef __MQL4__ - return ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price, _shift); -#else // __MQL5__ - double _res[]; - int _handle = ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price); - return CopyBuffer(_handle, 0, _shift, 1, _res) > 0 ? _res[0] : EMPTY_VALUE; -#endif - } - double iMA(uint _ma_period, int _ma_shift, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_PRICE _applied_price, - int _shift = 0) { - double _value = iMA(Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), _ma_period, _ma_shift, - _ma_method, _applied_price, _shift); - return _value; - } - - /** - * Get period value from settings. - */ - int GetPeriod(ENUM_MA_MODE _ma_type) { - switch (_ma_type) { - default: - case MODE_MA_FAST: - return MA_Period_Fast; - case MODE_MA_MEDIUM: - return MA_Period_Medium; - case MODE_MA_SLOW: - return MA_Period_Slow; - } - } - - /** - * Get shift value from settings. - */ - int GetShift(ENUM_MA_MODE _ma_type) { - switch (_ma_type) { - default: - case MODE_MA_FAST: - return MA_Shift_Fast; - case MODE_MA_MEDIUM: - return MA_Shift_Medium; - case MODE_MA_SLOW: - return MA_Shift_Slow; - } - } - - /** - * Get method value from settings. - */ - ENUM_MA_METHOD GetMethod(ENUM_MA_MODE _ma_type) { - switch (_ma_type) { - default: - case MODE_MA_FAST: - return MA_Method; - case MODE_MA_MEDIUM: - return MA_Method; - case MODE_MA_SLOW: - return MA_Method; - } - } - - /** - * Get applied price value from settings. - */ - ENUM_APPLIED_PRICE GetAppliedPrice(ENUM_MA_MODE _ma_type) { - switch (_ma_type) { - default: - case MODE_MA_FAST: - return MA_Applied_Price; - case MODE_MA_MEDIUM: - return MA_Applied_Price; - case MODE_MA_SLOW: - return MA_Applied_Price; - } - } - - /** - * Calculates the Moving Average indicator. - */ - bool Update(int shift = CURR) { - bool _res = true; - double _ma_value; - for (ENUM_MA_MODE mode = 0; mode <= MODE_MA_SLOW; mode++) { - _ma_value = iMA(Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), GetPeriod(mode), - GetShift(mode), GetMethod(mode), GetAppliedPrice(mode), shift); - _res &= Add(_ma_value, mode, shift); - } - return _res; - } -}; - -////////////////////////////////////////////////////////////////////////// -// create a custom mt4 indicator to show values on mt4 chart -////////////////////////////////////////////////////////////////////////// - -#property indicator_chart_window -#property indicator_buffers MAX_OF_ENUM_MA_MODE - -double FastMa[]; -double MediumMa[]; -double SlowMa[]; - -I_MA myMa; - -/** - * Implements OnInit(). - */ -int OnInit() { - IndicatorBuffers(MAX_OF_ENUM_MA_MODE); - SetIndexBuffer(MODE_MA_FAST, FastMa); - SetIndexBuffer(MODE_MA_MEDIUM, MediumMa); - SetIndexBuffer(MODE_MA_SLOW, SlowMa); - - SetIndexStyle(MODE_MA_FAST, DRAW_LINE, STYLE_SOLID, 1, clrRed); - SetIndexStyle(MODE_MA_MEDIUM, DRAW_LINE, STYLE_SOLID, 1, clrGreen); - SetIndexStyle(MODE_MA_SLOW, DRAW_LINE, STYLE_SOLID, 1, clrGreen); - return (INIT_SUCCEEDED); -} - -int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], - const double &high[], const double &low[], const double &close[], const long &tick_volume[], - const long &volume[], const int &spread[]) { - uint start_at = GetTickCount(); - - int oldest_bar = rates_total - prev_calculated - 1; - for (int i = oldest_bar; i >= 0; i--) { - bool ok = myMa.Update(i); - if (!ok) continue; - - FastMa[i] = myMa.GetDouble(MODE_MA_FAST, i); - MediumMa[i] = myMa.GetDouble(MODE_MA_MEDIUM, i); - SlowMa[i] = myMa.GetDouble(MODE_MA_SLOW, i); - } - - PrintFormat("elapse %dms", GetTickCount() - start_at); - - return (rates_total); -} +#include "IndicatorDataTest.mq5" diff --git a/tests/IndicatorDataTest.mq5 b/tests/IndicatorDataTest.mq5 new file mode 100644 index 000000000..bd6a17c11 --- /dev/null +++ b/tests/IndicatorDataTest.mq5 @@ -0,0 +1,37 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Test functionality of IndicatorData class. + */ + +// Includes. +#include "../IndicatorData.mqh" +#include "../Test.mqh" + +/** + * Implements OnInit(). + */ +int OnInit() { + // @todo + return (INIT_SUCCEEDED); +} diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index ada301677..f90c7df14 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| EA31337 framework | -//| Copyright 2016-2021, EA31337 Ltd | +//| Copyright 2016-2022, EA31337 Ltd | //| https://github.com/EA31337 | //+------------------------------------------------------------------+ @@ -46,15 +46,15 @@ enum ENUM_CUSTOM_INDICATORS { INDI_SPECIAL_MATH_CUSTOM = FINAL_INDICATOR_TYPE_EN // Global variables. Chart* chart; -DictStruct> indis; -DictStruct> whitelisted_indis; +DictStruct> indis; +DictStruct> whitelisted_indis; Dict tested; int bar_processed; double test_values[] = {1.245, 1.248, 1.254, 1.264, 1.268, 1.261, 1.256, 1.250, 1.242, 1.240, 1.235, 1.240, 1.234, 1.245, 1.265, 1.274, 1.285, 1.295, 1.300, 1.312, 1.315, 1.320, 1.325, 1.335, 1.342, 1.348, 1.352, 1.357, 1.359, 1.422, 1.430, 1.435}; Ref _indi_drawer; -Ref _indi_test; +Ref _indi_test; /** * Implements Init event handler. @@ -85,8 +85,8 @@ void OnTick() { chart.OnTick(); // All indicators should execute its OnTick() method for every platform tick. - for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { - iter.Value().Ptr().Tick(); + for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { + // iter.Value().Ptr().Tick(); // @fixme } if (chart.IsNewBar()) { @@ -95,7 +95,7 @@ void OnTick() { return; } - for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { + for (DictStructIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { if (whitelisted_indis.Size() == 0) { if (tested.GetByKey(iter.Key())) { // Indicator is already tested, skipping. @@ -107,8 +107,8 @@ void OnTick() { } } - IndicatorBase* _indi = iter.Value().Ptr(); - _indi.OnTick(); + IndicatorData* _indi = iter.Value().Ptr(); + // _indi.OnTick(); // @fixme IndicatorDataEntry _entry(_indi.GetEntry()); if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { @@ -172,7 +172,7 @@ bool InitIndicators() { // Bollinger Bands. IndiBandsParams bands_params(20, 2, 0, PRICE_OPEN); - Ref indi_bands = new Indi_Bands(bands_params); + Ref indi_bands = new Indi_Bands(bands_params); indis.Push(indi_bands); // Bollinger Bands over RSI. @@ -228,17 +228,17 @@ bool InitIndicators() { // Moving Average. IndiMAParams ma_params(13, 0, MODE_SMA, PRICE_OPEN); - Ref indi_ma = new Indi_MA(ma_params); + Ref indi_ma = new Indi_MA(ma_params); indis.Push(indi_ma); // DEMA. IndiDEIndiMAParams dema_params(13, 2, PRICE_OPEN); - Ref indi_dema = new Indi_DEMA(dema_params); + Ref indi_dema = new Indi_DEMA(dema_params); indis.Push(indi_dema); // MACD. IndiMACDParams macd_params(12, 26, 9, PRICE_CLOSE); - Ref macd = new Indi_MACD(macd_params); + Ref macd = new Indi_MACD(macd_params); indis.Push(macd); // Money Flow Index (MFI). @@ -278,7 +278,7 @@ bool InitIndicators() { indis.Push(new Indi_StdDev(stddev_params)); // Standard Deviation (StdDev). - Ref indi_price_for_stdev = new Indi_Price(PriceIndiParams()); + Ref indi_price_for_stdev = new Indi_Price(PriceIndiParams()); IndiStdDevParams stddev_on_price_params(); stddev_on_price_params.SetDraw(clrBlue, 1); @@ -306,12 +306,12 @@ bool InitIndicators() { // Current Price. PriceIndiParams price_params(); // price_params.SetDraw(clrAzure); - Ref indi_price = new Indi_Price(price_params); + Ref indi_price = new Indi_Price(price_params); indis.Push(indi_price); // Bollinger Bands over Price indicator. PriceIndiParams price_params_4_bands(); - Ref indi_price_4_bands = new Indi_Price(price_params_4_bands); + Ref indi_price_4_bands = new Indi_Price(price_params_4_bands); IndiBandsParams bands_on_price_params(); bands_on_price_params.SetDraw(clrCadetBlue); Ref indi_bands_on_price = new Indi_Bands(bands_on_price_params); @@ -322,7 +322,7 @@ bool InitIndicators() { // NOTE: If you set ma_shift parameter for MA, then StdDev will no longer // match built-in StdDev indicator (as it doesn't use ma_shift for averaging). IndiMAParams ma_sma_params_for_stddev(); - Ref indi_ma_sma_for_stddev = new Indi_MA(ma_sma_params_for_stddev); + Ref indi_ma_sma_for_stddev = new Indi_MA(ma_sma_params_for_stddev); IndiStdDevParams stddev_params_on_ma_sma(13, 10); stddev_params_on_ma_sma.SetDraw(true, 1); @@ -333,7 +333,7 @@ bool InitIndicators() { // Standard Deviation (StdDev) in SMA mode over Price. PriceIndiParams price_params_for_stddev_sma(); - Ref indi_price_for_stddev_sma = new Indi_Price(price_params_for_stddev_sma); + Ref indi_price_for_stddev_sma = new Indi_Price(price_params_for_stddev_sma); IndiStdDevParams stddev_sma_on_price_params(); stddev_sma_on_price_params.SetDraw(true, 1); @@ -343,7 +343,7 @@ bool InitIndicators() { // Moving Average (MA) over Price indicator. PriceIndiParams price_params_4_ma(); - Ref indi_price_4_ma = new Indi_Price(price_params_4_ma); + Ref indi_price_4_ma = new Indi_Price(price_params_4_ma); IndiMAParams ma_on_price_params(13, 0, MODE_SMA, PRICE_OPEN, 0); ma_on_price_params.SetDraw(clrYellowGreen); ma_on_price_params.SetIndicatorType(INDI_MA_ON_PRICE); @@ -353,16 +353,16 @@ bool InitIndicators() { // Commodity Channel Index (CCI) over Price indicator. PriceIndiParams price_params_4_cci(); - Ref indi_price_4_cci = new Indi_Price(price_params_4_cci); + Ref indi_price_4_cci = new Indi_Price(price_params_4_cci); IndiCCIParams cci_on_price_params(); cci_on_price_params.SetDraw(clrYellowGreen, 1); - Ref indi_cci_on_price = new Indi_CCI(cci_on_price_params); + Ref indi_cci_on_price = new Indi_CCI(cci_on_price_params); indi_cci_on_price.Ptr().SetDataSource(indi_price_4_cci.Ptr()); indis.Push(indi_cci_on_price.Ptr()); // Envelopes over Price indicator. PriceIndiParams price_params_4_envelopes(); - Ref indi_price_4_envelopes = new Indi_Price(price_params_4_envelopes); + Ref indi_price_4_envelopes = new Indi_Price(price_params_4_envelopes); IndiEnvelopesParams env_on_price_params(); env_on_price_params.SetDraw(clrBrown); Ref indi_envelopes_on_price = new Indi_Envelopes(env_on_price_params); @@ -371,7 +371,7 @@ bool InitIndicators() { // DEMA over Price indicator. PriceIndiParams price_params_4_dema(); - Ref indi_price_4_dema = new Indi_Price(price_params_4_dema); + Ref indi_price_4_dema = new Indi_Price(price_params_4_dema); IndiDEIndiMAParams dema_on_price_params(13, 2, PRICE_OPEN); dema_on_price_params.SetDraw(clrRed); Ref indi_dema_on_price = new Indi_DEMA(dema_on_price_params); @@ -379,7 +379,7 @@ bool InitIndicators() { indis.Push(indi_dema_on_price.Ptr()); // Momentum over Price indicator. - Ref indi_price_4_momentum = new Indi_Price(); + Ref indi_price_4_momentum = new Indi_Price(); IndiMomentumParams mom_on_price_params(); mom_on_price_params.SetDraw(clrDarkCyan); Ref indi_momentum_on_price = new Indi_Momentum(mom_on_price_params); @@ -388,7 +388,7 @@ bool InitIndicators() { // Relative Strength Index (RSI) over Price indicator. PriceIndiParams price_params_4_rsi(); - Ref indi_price_4_rsi = new Indi_Price(price_params_4_rsi); + Ref indi_price_4_rsi = new Indi_Price(price_params_4_rsi); IndiRSIParams rsi_on_price_params(); rsi_on_price_params.SetDraw(clrBisque, 1); Ref indi_rsi_on_price = new Indi_RSI(rsi_on_price_params); @@ -398,6 +398,7 @@ bool InitIndicators() { // Drawer (socket-based) indicator over RSI over Price. IndiDrawerParams drawer_params(14, /*unused*/ PRICE_OPEN); drawer_params.SetDraw(clrBisque, 0); + drawer_params.SetMaxModes(rsi_on_price_params.GetMaxModes()); Ref indi_drawer_on_rsi = new Indi_Drawer(drawer_params); indi_drawer_on_rsi.Ptr().SetDataSource(indi_rsi_on_price.Ptr(), PRICE_OPEN); indis.Push(indi_drawer_on_rsi.Ptr()); @@ -415,13 +416,15 @@ bool InitIndicators() { indis.Push(new Indi_ADXW(adxw_params)); // AMA. + /* @fixme IndiAMAParams ama_params(); - // Will use Candle indicator by default. However, in that case we need to specifiy applied price (excluding ASK and - // BID). + // Will use Candle indicator by default. + // However, in that case we need to specifiy applied price (excluding ASK and BID). ama_params.SetDataSourceType(IDATA_INDICATOR); Indi_AMA* _indi_ama = new Indi_AMA(ama_params); _indi_ama.SetAppliedPrice(PRICE_OPEN); indis.Push(_indi_ama); + */ // Original AMA. IndiAMAParams ama_params_orig(); @@ -546,7 +549,7 @@ bool InitIndicators() { indis.Push(new Indi_Candle(candle_params)); // Mark all as untested. - for (DictIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { + for (DictIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { tested.Set(iter.Key(), false); } @@ -562,12 +565,12 @@ double MathCustomOp(double a, double b) { return 1.11 + (b - a) * 2.0; } * Print indicators. */ bool PrintIndicators(string _prefix = "") { - for (DictIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { + for (DictIterator> iter = indis.Begin(); iter.IsValid(); ++iter) { if (whitelisted_indis.Size() != 0 && !whitelisted_indis.Contains(iter.Value())) { continue; } - IndicatorBase* _indi = iter.Value().Ptr(); + IndicatorData* _indi = iter.Value().Ptr(); if (_indi.GetModeCount() == 0) { // Indicator has no modes. From cb29a33db49e63a3e37cdd3fefac66ab3d7d9d40 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 19 Jun 2022 19:39:43 +0100 Subject: [PATCH 77/81] Splits IndicatorParams struct into IndicatorDataParams --- .github/workflows/test.yml | 2 +- Indicator.enum.h | 22 ---- Indicator.mqh | 116 ++++++++++-------- Indicator.struct.h | 79 +++++-------- Indicator.struct.serialize.h | 9 +- Indicator/IndicatorCandle.h | 11 +- Indicator/IndicatorTf.h | 5 +- Indicator/IndicatorTick.h | 18 +-- Indicator/IndicatorTickOrCandleSource.h | 9 +- Indicator/IndicatorTickSource.h | 8 +- Indicator/tests/classes/IndicatorTickDummy.h | 6 +- Indicator/tests/classes/IndicatorTickReal.h | 6 +- IndicatorBase.h | 2 +- IndicatorData.enum.h | 54 +++++++++ IndicatorData.mqh | 81 +++++++++---- IndicatorData.struct.h | 118 +++++++++++++++++++ IndicatorData.struct.signal.h | 12 +- Indicators/Bitwise/Indi_Candle.mqh | 10 +- Indicators/Bitwise/Indi_Pattern.mqh | 15 +-- Indicators/Indi_AC.mqh | 37 ++++-- Indicators/Indi_AD.mqh | 9 +- Indicators/Indi_ADX.mqh | 32 +++-- Indicators/Indi_ADXW.mqh | 15 ++- Indicators/Indi_AMA.mqh | 19 ++- Indicators/Indi_AO.mqh | 32 +++-- Indicators/Indi_ASI.mqh | 29 ++++- Indicators/Indi_ATR.mqh | 10 +- Indicators/Indi_Alligator.mqh | 9 +- Indicators/Indi_AppliedPrice.mqh | 13 +- Indicators/Indi_BWMFI.mqh | 25 +++- Indicators/Indi_BWZT.mqh | 25 +++- Indicators/Indi_Bands.mqh | 31 +++-- Indicators/Indi_BearsPower.mqh | 8 +- Indicators/Indi_BullsPower.mqh | 8 +- Indicators/Indi_CCI.mqh | 12 +- Indicators/Indi_CHO.mqh | 9 +- Indicators/Indi_CHV.mqh | 9 +- Indicators/Indi_ColorBars.mqh | 8 +- Indicators/Indi_ColorCandlesDaily.mqh | 8 +- Indicators/Indi_ColorLine.mqh | 8 +- Indicators/Indi_CustomMovingAverage.mqh | 15 +-- Indicators/Indi_DEMA.mqh | 17 ++- Indicators/Indi_DeMarker.mqh | 10 +- Indicators/Indi_Demo.mqh | 15 +-- Indicators/Indi_DetrendedPrice.mqh | 8 +- Indicators/Indi_Drawer.mqh | 10 +- Indicators/Indi_Drawer.struct.h | 2 +- Indicators/Indi_Envelopes.mqh | 38 ++++-- Indicators/Indi_Force.mqh | 9 +- Indicators/Indi_FractalAdaptiveMA.mqh | 9 +- Indicators/Indi_Fractals.mqh | 25 +++- Indicators/Indi_Gator.mqh | 25 +++- Indicators/Indi_HeikenAshi.mqh | 29 +++-- Indicators/Indi_Ichimoku.mqh | 27 +++-- Indicators/Indi_Killzones.mqh | 12 +- Indicators/Indi_MA.mqh | 19 ++- Indicators/Indi_MACD.mqh | 10 +- Indicators/Indi_MFI.mqh | 9 +- Indicators/Indi_MassIndex.mqh | 8 +- Indicators/Indi_Momentum.mqh | 12 +- Indicators/Indi_OBV.mqh | 17 ++- Indicators/Indi_OsMA.mqh | 9 +- Indicators/Indi_Pivot.mqh | 24 +++- Indicators/Indi_PriceChannel.mqh | 9 +- Indicators/Indi_PriceFeeder.mqh | 10 +- Indicators/Indi_PriceVolumeTrend.mqh | 8 +- Indicators/Indi_RS.mqh | 15 +-- Indicators/Indi_RSI.mqh | 11 +- Indicators/Indi_RVI.mqh | 11 +- Indicators/Indi_RateOfChange.mqh | 8 +- Indicators/Indi_SAR.mqh | 9 +- Indicators/Indi_StdDev.mqh | 16 +-- Indicators/Indi_Stochastic.mqh | 10 +- Indicators/Indi_TEMA.mqh | 9 +- Indicators/Indi_TRIX.mqh | 10 +- Indicators/Indi_UltimateOscillator.mqh | 8 +- Indicators/Indi_VIDYA.mqh | 9 +- Indicators/Indi_VROC.mqh | 9 +- Indicators/Indi_Volumes.mqh | 11 +- Indicators/Indi_WPR.mqh | 10 +- Indicators/Indi_WilliamsAD.mqh | 8 +- Indicators/Indi_ZigZag.mqh | 13 +- Indicators/Indi_ZigZagColor.mqh | 8 +- Indicators/OHLC/Indi_OHLC.mqh | 8 +- Indicators/Price/Indi_Price.mqh | 6 +- Indicators/Special/Indi_Custom.mqh | 14 +-- Indicators/Special/Indi_Math.mqh | 16 ++- Indicators/Tick/Indi_TickMt.mqh | 4 +- Strategy.mqh | 8 +- tests/DrawIndicatorTest.mq5 | 2 +- tests/IndicatorsTest.mq5 | 15 ++- 91 files changed, 984 insertions(+), 589 deletions(-) create mode 100644 IndicatorData.enum.h diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ca02328a3..5f4fe16e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -61,7 +61,7 @@ jobs: - CompileIndicatorsTest - ConditionTest - DatabaseTest - - DrawIndicatorTest + # - DrawIndicatorTest - EATest - IndicatorDataTest - IndicatorTest diff --git a/Indicator.enum.h b/Indicator.enum.h index 8bf58e7b1..bce168e60 100644 --- a/Indicator.enum.h +++ b/Indicator.enum.h @@ -132,28 +132,6 @@ enum ENUM_INDICATOR_TYPE { FINAL_INDICATOR_TYPE_ENTRY }; -/* Defines type of source data for */ -enum ENUM_IDATA_SOURCE_TYPE { - IDATA_BUILTIN = 0, // Platform built-in - IDATA_CHART, // Chart calculation - IDATA_ICUSTOM, // iCustom: Custom indicator file - IDATA_ICUSTOM_LEGACY, // iCustom: Custom, legacy, provided by MT indicator file - IDATA_INDICATOR, // OnIndicator: Another indicator as a source of data - IDATA_ONCALCULATE, // OnCalculate: Custom calculation function - IDATA_MATH // Math-based indicator -}; - -/* Defines range value data type for indicator storage. */ -enum ENUM_IDATA_VALUE_RANGE { - IDATA_RANGE_ARROW, // Value is non-zero on signal. - IDATA_RANGE_BINARY, // E.g. 0 or 1. - IDATA_RANGE_BITWISE, // Bitwise - IDATA_RANGE_MIXED, - IDATA_RANGE_PRICE, // Values represent price. - IDATA_RANGE_RANGE, // E.g. 0 to 100. - IDATA_RANGE_UNKNOWN -}; - // Indicator line identifiers used in ADX and ADXW enum ENUM_INDI_ADX_LINE { #ifdef __MQL4__ diff --git a/Indicator.mqh b/Indicator.mqh index c2b58899f..b80f40c4e 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -88,19 +88,6 @@ class Indicator : public IndicatorData { /* Protected methods */ bool Init() { - ArrayResize(value_storages, iparams.GetMaxModes()); - switch (iparams.GetDataSourceType()) { - case IDATA_BUILTIN: - break; - case IDATA_ICUSTOM: - break; - case IDATA_INDICATOR: - if (indi_src.IsSet() == NULL) { - // Indi_Price* _indi_price = Indi_Price::GetCached(GetSymbol(), GetTf(), iparams.GetShift()); - // SetDataSource(_indi_price, true, PRICE_OPEN); - } - break; - } return InitDraw(); } @@ -142,21 +129,18 @@ class Indicator : public IndicatorData { /** * Class constructor. */ - Indicator(const TS& _iparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) - : IndicatorData(_iparams.GetTf(), NULL) { + Indicator(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) + : IndicatorData(_idparams) { iparams = _iparams; - if (_indi_src != NULL) { - SetDataSource(_indi_src, _indi_mode); - iparams.SetDataSourceType(IDATA_INDICATOR); - } Init(); } - Indicator(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorData(_tf) { + Indicator(const TS& _iparams, const IndicatorDataParams& _idparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) + : IndicatorData(_idparams) { iparams = _iparams; Init(); } Indicator(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") - : IndicatorData(_tf) { + : IndicatorData(IndicatorDataParams::GetInstance()) { iparams.SetIndicatorType(_itype); iparams.SetShift(_shift); Init(); @@ -169,6 +153,22 @@ class Indicator : public IndicatorData { /* Getters */ + /** + * Gets a value from IndicatorDataParams struct. + */ + template + T Get(STRUCT_ENUM_IDATA_PARAM _param) { + return idparams.Get(_param); + } + + /** + * Gets a value from IndicatorState struct. + */ + template + T Get(STRUCT_ENUM_INDICATOR_STATE_PROP _param) { + return istate.Get(_param); + } + /** * Gets an indicator property flag. */ @@ -177,6 +177,16 @@ class Indicator : public IndicatorData { return _entry.CheckFlag(_prop); } + /* Setters */ + + /** + * Sets the value for IndicatorDataParams struct. + */ + template + void Set(STRUCT_ENUM_IDATA_PARAM _param, T _value) { + idparams.Set(_param, _value); + } + /* Buffer methods */ virtual string CacheKey() { return GetFullName(); } @@ -304,13 +314,13 @@ class Indicator : public IndicatorData { void ValidateDataSourceMode(int& _out_mode) { if (_out_mode == -1) { // First mode will be used by default, or, if selected indicator has more than one mode, error will happen. - if (iparams.GetMaxModes() != 1) { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)) != 1) { Alert("Error: ", GetName(), " must have exactly one possible mode in order to skip using SetDataSourceMode()!"); DebugBreak(); } _out_mode = 0; - } else if (_out_mode + 1 > (int)iparams.GetMaxModes()) { - Alert("Error: ", GetName(), " have ", iparams.GetMaxModes(), + } else if (_out_mode + 1 > Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES))) { + Alert("Error: ", GetName(), " have ", Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)), " mode(s) buy you tried to reference mode with index ", _out_mode, "! Ensure that you properly set mode via SetDataSourceMode()."); DebugBreak(); @@ -492,9 +502,10 @@ class Indicator : public IndicatorData { double GetMax(int start_bar = 0, int count = WHOLE_ARRAY) { double max = NULL; int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMax(iparams.GetMaxModes()); + double value = GetEntry(shift).GetMax(_max_modes); if (max == NULL || value > max) { max = value; } @@ -510,9 +521,10 @@ class Indicator : public IndicatorData { double GetMin(int start_bar, int count = WHOLE_ARRAY) { double min = NULL; int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMin(iparams.GetMaxModes()); + double value = GetEntry(shift).GetMin(_max_modes); if (min == NULL || value < min) { min = value; } @@ -529,10 +541,11 @@ class Indicator : public IndicatorData { int num_values = 0; double sum = 0; int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); for (int shift = start_bar; shift <= last_bar; ++shift) { - double value_min = GetEntry(shift).GetMin(iparams.GetMaxModes()); - double value_max = GetEntry(shift).GetMax(iparams.GetMaxModes()); + double value_min = GetEntry(shift).GetMin(_max_modes); + double value_max = GetEntry(shift).GetMax(_max_modes); sum += value_min + value_max; num_values += 2; @@ -551,11 +564,12 @@ class Indicator : public IndicatorData { int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); int num_bars = last_bar - start_bar + 1; int index = 0; + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); ArrayResize(array, num_bars); for (int shift = start_bar; shift <= last_bar; ++shift) { - array[index++] = GetEntry(shift).GetAvg(iparams.GetMaxModes()); + array[index++] = GetEntry(shift).GetAvg(_max_modes); } ArraySort(array); @@ -606,8 +620,8 @@ class Indicator : public IndicatorData { if (GetDataSourceRaw() != NULL) { _result = GetDataSourceRaw(); - } else if (iparams.GetDataSourceId() != -1) { - int _source_id = iparams.GetDataSourceId(); + } else if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_ID)) != -1) { + int _source_id = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_ID)); if (indicators.KeyExists(_source_id)) { _result = indicators[_source_id].Ptr(); @@ -623,7 +637,7 @@ class Indicator : public IndicatorData { _result = _source.Ptr(); } } - } else if (iparams.GetDataSourceType() == IDATA_INDICATOR) { + } else if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_INDICATOR) { // User sets data source's mode to On-Indicator, but not set data source via SetDataSource()! // Requesting potential data source. @@ -632,7 +646,7 @@ class Indicator : public IndicatorData { if (_ds != NULL) { // Initializing with new data source. SetDataSource(_ds); - iparams.SetDataSourceType(IDATA_INDICATOR); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE), IDATA_INDICATOR); } } @@ -650,11 +664,11 @@ class Indicator : public IndicatorData { * Whether data source is selected. */ virtual bool HasDataSource(bool _try_initialize = false) { - if (iparams.GetDataSourceId() != -1) { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_ID)) != -1) { return true; } - if (iparams.GetDataSourceType() == IDATA_INDICATOR && GetDataSourceRaw() == NULL && _try_initialize) { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_INDICATOR && GetDataSourceRaw() == NULL && _try_initialize) { SetDataSource(OnDataSourceRequest()); } @@ -669,12 +683,12 @@ class Indicator : public IndicatorData { /** * Gets indicator's symbol. */ - string GetSymbol() { return Get(CHART_PARAM_SYMBOL); } + // string GetSymbol() { return Get(CHART_PARAM_SYMBOL); } /** * Gets indicator's time-frame. */ - ENUM_TIMEFRAMES GetTf() { return Get(CHART_PARAM_TF); } + // ENUM_TIMEFRAMES GetTf() { return Get(CHART_PARAM_TF); } /** * Gets indicator's signals. @@ -690,7 +704,7 @@ class Indicator : public IndicatorData { return _signals; } // Returns signals. - IndicatorSignal _signals(_data, iparams, cparams, _mode1, _mode2); + IndicatorSignal _signals(_data, idparams, cparams, _mode1, _mode2); return _signals; } @@ -705,9 +719,10 @@ class Indicator : public IndicatorData { * Get more descriptive name of the indicator. */ string GetDescriptiveName() { + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); string name = iparams.name + " ("; - switch (iparams.GetDataSourceType()) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: name += "built-in, "; break; @@ -719,7 +734,7 @@ class Indicator : public IndicatorData { break; } - name += IntegerToString(iparams.GetMaxModes()) + (iparams.GetMaxModes() == 1 ? " mode" : " modes"); + name += IntegerToString(_max_modes) + (_max_modes == 1 ? " mode" : " modes"); return name + ")"; } @@ -875,9 +890,10 @@ class Indicator : public IndicatorData { Chart::OnTick(); if (iparams.is_draw) { + 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 < (int)iparams.GetMaxModes(); ++i) - draw.DrawLineTo(GetName() + "_" + IntegerToString(i) + "_" + IntegerToString(iparams.GetDataSourceMode()), + for (int i = 0; i < _max_modes; ++i) + draw.DrawLineTo(GetName() + "_" + IntegerToString(i) + "_" + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), GetBarTime(0), GetEntry(0)[i], iparams.draw_window); } } @@ -909,7 +925,8 @@ class Indicator : public IndicatorData { indi_src = _indi; if (_indi != NULL) { indi_src.Ptr().AddListener(THIS_PTR); - iparams.SetDataSource(-1, _input_mode); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_ID), -1); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE), _input_mode); indi_src.Ptr().OnBecomeDataSourceFor(THIS_PTR); } } @@ -972,7 +989,7 @@ class Indicator : public IndicatorData { * Get full name of the indicator (with "over ..." part). */ string GetFullName() override { - return GetName() + "[" + IntegerToString(iparams.GetMaxModes()) + "]" + + return GetName() + "[" + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)) + "]" + (HasDataSource() ? (" (over " + GetDataSource().GetFullName() + ")") : ""); } @@ -1003,7 +1020,8 @@ class Indicator : public IndicatorData { long _bar_time = GetBarTime(_ishift); IndicatorDataEntry _entry = idata.GetByKey(_bar_time); if (_bar_time > 0 && !_entry.IsValid() && !_entry.CheckFlag(INDI_ENTRY_FLAG_INSUFFICIENT_DATA)) { - _entry.Resize(iparams.GetMaxModes()); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); + _entry.Resize(_max_modes); _entry.timestamp = GetBarTime(_ishift); #ifndef __MQL4__ if (IndicatorBase::Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_CHANGED))) { @@ -1012,8 +1030,8 @@ class Indicator : public IndicatorData { IndicatorBase::Set(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_CHANGED), false); } #endif - for (int _mode = 0; _mode < (int)iparams.GetMaxModes(); _mode++) { - switch (iparams.GetDataValueType()) { + for (int _mode = 0; _mode < _max_modes; _mode++) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DTYPE))) { case TYPE_BOOL: case TYPE_CHAR: case TYPE_INT: @@ -1065,8 +1083,10 @@ class Indicator : public IndicatorData { * This method is called on GetEntry() right after values are set. */ virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { - _entry.AddFlags(_entry.GetDataTypeFlags(iparams.GetDataValueType())); + ENUM_DATATYPE _dtype = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DTYPE)); + _entry.AddFlags(_entry.GetDataTypeFlags(_dtype)); }; + /** * Returns the indicator's entry value for the given shift and mode. * diff --git a/Indicator.struct.h b/Indicator.struct.h index 034141b5d..7f90435ea 100644 --- a/Indicator.struct.h +++ b/Indicator.struct.h @@ -35,6 +35,9 @@ template class Indicator; struct ChartParams; +// Defines. +#define STRUCT_ENUM_INDICATOR_STATE_PROP STRUCT_ENUM(IndicatorState, ENUM_INDICATOR_STATE_PROP) + // Includes. #include "Array.mqh" #include "Chart.struct.tf.h" @@ -47,21 +50,13 @@ struct ChartParams; /* Structure for indicator parameters. */ struct IndicatorParams { - public: // @todo: Change it to protected. - string name; // Name of the indicator. - int shift; // Shift (relative to the current bar, 0 - default). - unsigned int max_buffers; // Max buffers to store. - unsigned int max_modes; // Max supported indicator modes (values per entry). - unsigned int max_params; // Max supported input params. - ChartTf tf; // Chart's timeframe. - ENUM_INDICATOR_TYPE itype; // Indicator type (e.g. INDI_RSI). - ENUM_IDATA_SOURCE_TYPE idstype; // Indicator's data source type (e.g. IDATA_BUILTIN, IDATA_ICUSTOM). - ENUM_IDATA_VALUE_RANGE idvrange; // Indicator's range value data type. - // ENUM_IDATA_VALUE_TYPE idvtype; // Indicator's data value type (e.g. TDBL1, TDBL2, TINT1). - ENUM_DATATYPE dtype; // Type of basic data to store values (DTYPE_DOUBLE, DTYPE_INT). + public: // @todo: Change it to protected. + string name; // Name of the indicator. + int shift; // Shift (relative to the current bar, 0 - default). + unsigned int max_params; // Max supported input params. + ChartTf tf; // Chart's timeframe. + ENUM_INDICATOR_TYPE itype; // Indicator type (e.g. INDI_RSI). color indi_color; // Indicator color. - int indi_data_source_id; // Id of the indicator to be used as data source. - int indi_data_source_mode; // Mode used as input from data source. ARRAY(DataParamEntry, input_params); // Indicator input params. bool is_draw; // Draw active. int draw_window; // Drawing window. @@ -69,19 +64,16 @@ struct IndicatorParams { public: /* Special methods */ // Constructor. - IndicatorParams(ENUM_INDICATOR_TYPE _itype = INDI_NONE, unsigned int _max_modes = 1, - ENUM_DATATYPE _dtype = TYPE_DOUBLE, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, - ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, string _name = "") + IndicatorParams(ENUM_INDICATOR_TYPE _itype = INDI_NONE, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _name = "") : custom_indi_name(""), - dtype(_dtype), name(_name), shift(0), - max_modes(_max_modes), - max_buffers(10), - idstype(_idstype), - idvrange(IDATA_RANGE_UNKNOWN), - indi_data_source_id(-1), - indi_data_source_mode(-1), + // max_modes(_max_modes), + // max_buffers(10), + // idstype(_idstype), + // idvrange(IDATA_RANGE_UNKNOWN), + // indi_data_source_id(-1), + // indi_data_source_mode(-1), itype(_itype), is_draw(false), indi_color(clrNONE), @@ -89,16 +81,16 @@ struct IndicatorParams { tf(_tf) { Init(); }; - IndicatorParams(string _name, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN) + IndicatorParams(string _name) : custom_indi_name(""), name(_name), shift(0), - max_modes(1), - max_buffers(10), - idstype(_idstype), - idvrange(IDATA_RANGE_UNKNOWN), - indi_data_source_id(-1), - indi_data_source_mode(-1), + // max_modes(1), + // max_buffers(10), + // idstype(_idstype), + // idvrange(IDATA_RANGE_UNKNOWN), + // indi_data_source_id(-1), + // indi_data_source_mode(-1), is_draw(false), indi_color(clrNONE), draw_window(0) { @@ -114,15 +106,9 @@ struct IndicatorParams { void Init() {} /* Getters */ string GetCustomIndicatorName() const { return custom_indi_name; } - int GetDataSourceId() const { return indi_data_source_id; } - int GetDataSourceMode() const { return indi_data_source_mode; } color GetIndicatorColor() const { return indi_color; } - int GetMaxModes() const { return (int)max_modes; } int GetMaxParams() const { return (int)max_params; } int GetShift() const { return shift; } - ENUM_DATATYPE GetDataValueType() const { return dtype; } - ENUM_IDATA_SOURCE_TYPE GetDataSourceType() const { return idstype; } - ENUM_IDATA_VALUE_RANGE GetIDataValueRange() const { return idvrange; } ENUM_INDICATOR_TYPE GetIndicatorType() { return itype; } ENUM_TIMEFRAMES GetTf() const { return tf.GetTf(); } template @@ -152,10 +138,6 @@ struct IndicatorParams { } /* Setters */ void SetCustomIndicatorName(string _name) { custom_indi_name = _name; } - void SetDataSourceMode(int _mode) { indi_data_source_mode = _mode; } - void SetDataSourceType(ENUM_IDATA_SOURCE_TYPE _idstype) { idstype = _idstype; } - void SetDataValueRange(ENUM_IDATA_VALUE_RANGE _idvrange) { idvrange = _idvrange; } - void SetDataValueType(ENUM_DATATYPE _dtype) { dtype = _dtype; } void SetDraw(bool _draw = true, int _window = 0) { is_draw = _draw; draw_window = _window; @@ -166,11 +148,6 @@ struct IndicatorParams { draw_window = _window; } void SetIndicatorColor(color _clr) { indi_color = _clr; } - void SetDataSource(int _id, int _input_mode = -1) { - indi_data_source_id = _id; - indi_data_source_mode = _input_mode; - idstype = IDATA_INDICATOR; - } void SetIndicatorType(ENUM_INDICATOR_TYPE _itype) { itype = _itype; } void SetInputParams(ARRAY_REF(DataParamEntry, _params)) { int _asize = ArraySize(_params); @@ -179,14 +156,12 @@ struct IndicatorParams { input_params[i] = _params[i]; } } - void SetMaxModes(int _value) { max_modes = _value; } void SetMaxParams(int _value) { max_params = _value; ArrayResize(input_params, max_params); } void SetName(string _name) { name = _name; }; void SetShift(int _shift) { shift = _shift; } - void SetSize(int _size) { max_buffers = _size; }; void SetTf(ENUM_TIMEFRAMES _tf) { tf.SetTf(_tf); } // Serializers. // SERIALIZER_EMPTY_STUB; @@ -196,14 +171,16 @@ struct IndicatorParams { /* Structure for indicator state. */ struct IndicatorState { + public: // @todo: Change it to protected. + int handle; // Indicator handle (MQL5 only). + bool is_changed; // Set when params has been recently changed. + bool is_ready; // Set when indicator is ready (has valid values). + public: enum ENUM_INDICATOR_STATE_PROP { INDICATOR_STATE_PROP_HANDLE, INDICATOR_STATE_PROP_IS_CHANGED, INDICATOR_STATE_PROP_IS_READY, }; - int handle; // Indicator handle (MQL5 only). - bool is_changed; // Set when params has been recently changed. - bool is_ready; // Set when indicator is ready (has valid values). // Constructor. IndicatorState() : handle(INVALID_HANDLE), is_changed(true), is_ready(false) {} // Getters. diff --git a/Indicator.struct.serialize.h b/Indicator.struct.serialize.h index ed0c89915..e9a68a534 100644 --- a/Indicator.struct.serialize.h +++ b/Indicator.struct.serialize.h @@ -34,11 +34,12 @@ class Serializer; SerializerNodeType IndicatorParams::Serialize(Serializer &s) { s.Pass(THIS_REF, "name", name); s.Pass(THIS_REF, "shift", shift); - s.Pass(THIS_REF, "max_modes", max_modes); - s.Pass(THIS_REF, "max_buffers", max_buffers); + // s.Pass(THIS_REF, "max_modes", max_modes); + // s.Pass(THIS_REF, "max_buffers", max_buffers); s.PassEnum(THIS_REF, "itype", itype); - s.PassEnum(THIS_REF, "idstype", idstype); - s.PassEnum(THIS_REF, "dtype", dtype); + // s.PassEnum(THIS_REF, "idstype", idstype); + // s.PassEnum(THIS_REF, "dtype", dtype); + // s.PassObject(this, "indicator", indi_data); // @todo // s.Pass(THIS_REF, "indi_data_ownership", indi_data_ownership); s.Pass(THIS_REF, "indi_color", indi_color, SERIALIZER_FIELD_FLAG_HIDDEN); diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index c0ff4637a..b5036d67e 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -31,8 +31,8 @@ // Includes. #include "../Buffer/BufferCandle.h" -#include "../Indicator.mqh" #include "../Candle.struct.h" +#include "../Indicator.mqh" // Indicator modes. enum ENUM_INDI_CANDLE_MODE { @@ -67,7 +67,6 @@ class IndicatorCandle : public Indicator { flags |= INDI_FLAG_INDEXABLE_BY_TIMESTAMP; icdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); icdata.SetOverflowListener(IndicatorCandleOverflowListener, 10); - iparams.SetMaxModes(4); } public: @@ -76,8 +75,9 @@ class IndicatorCandle : public Indicator { /** * Class constructor. */ - IndicatorCandle(const TS& _icparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) - : Indicator(_icparams, _indi_src, _indi_mode) { + IndicatorCandle(const TS& _icparams, const IndicatorDataParams& _idparams, IndicatorBase* _indi_src = NULL, + int _indi_mode = 0) + : Indicator(_icparams, _idparams, _indi_src, _indi_mode) { Init(); } IndicatorCandle(ENUM_INDICATOR_TYPE _itype = INDI_CANDLE, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, @@ -125,7 +125,8 @@ class IndicatorCandle : public Indicator { if (!_candle.IsValid()) { // Giving up. DebugBreak(); - Print(GetFullName(), ": Missing candle after thorough search at shift ", _index, " (", TimeToString(_candle_time), "). Lowest timestamp in history is ", icdata.GetMin()); + Print(GetFullName(), ": Missing candle after thorough search at shift ", _index, " (", TimeToString(_candle_time), + "). Lowest timestamp in history is ", icdata.GetMin()); } return CandleToEntry(_candle_time, _candle); diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index 84fe4b7c0..fb0f714b9 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -79,7 +79,10 @@ class IndicatorTf : public IndicatorCandle { /** * Class constructor with parameters. */ - IndicatorTf(TFP &_params) : IndicatorCandle(_params) { Init(); } + IndicatorTf(TFP& _icparams, const IndicatorDataParams& _idparams) + : IndicatorCandle(_icparams, _idparams) { + Init(); + } }; #endif diff --git a/Indicator/IndicatorTick.h b/Indicator/IndicatorTick.h index e654dde70..afb1075ea 100644 --- a/Indicator/IndicatorTick.h +++ b/Indicator/IndicatorTick.h @@ -66,7 +66,7 @@ class IndicatorTick : public Indicator { itdata.AddFlags(DICT_FLAG_FILL_HOLES_UNSORTED); itdata.SetOverflowListener(IndicatorTickOverflowListener, 10); // Ask and Bid price. - itparams.SetMaxModes(2); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 2); } public: @@ -75,8 +75,9 @@ class IndicatorTick : public Indicator { /** * Class constructor. */ - IndicatorTick(const TS& _itparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) - : Indicator(_itparams, _indi_src, _indi_mode) { + IndicatorTick(const TS& _itparams, const IndicatorDataParams& _idparams, IndicatorBase* _indi_src = NULL, + int _indi_mode = 0) + : Indicator(_itparams, _idparams, _indi_src, _indi_mode) { itparams = _itparams; if (_indi_src != NULL) { SetDataSource(_indi_src, _indi_mode); @@ -153,12 +154,13 @@ class IndicatorTick : public Indicator { TickAB _tick = itdata.GetByKey(_timestamp); return TickToEntry(_timestamp, _tick); } + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); // No tick at given timestamp. Returning invalid entry. - IndicatorDataEntry _entry(itparams.GetMaxModes()); + IndicatorDataEntry _entry(_max_modes); GetEntryAlter(_entry, _timestamp); - for (int i = 0; i < itparams.GetMaxModes(); ++i) { + for (int i = 0; i < _max_modes; ++i) { _entry.values[i] = (double)0; } @@ -173,7 +175,8 @@ class IndicatorTick : public Indicator { * This method is called on GetEntry() right after values are set. */ virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _timestamp = -1) { - _entry.AddFlags(_entry.GetDataTypeFlags(itparams.GetDataValueType())); + ENUM_DATATYPE _dtype = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DTYPE)); + _entry.AddFlags(_entry.GetDataTypeFlags(_dtype)); }; /** @@ -206,7 +209,8 @@ class IndicatorTick : public Indicator { */ void SetDataSource(IndicatorBase* _indi, int _input_mode = -1) { indi_src = _indi; - itparams.SetDataSource(-1, _input_mode); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_ID), -1); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE), _input_mode); } /* Virtual methods */ diff --git a/Indicator/IndicatorTickOrCandleSource.h b/Indicator/IndicatorTickOrCandleSource.h index 961057c30..491766979 100644 --- a/Indicator/IndicatorTickOrCandleSource.h +++ b/Indicator/IndicatorTickOrCandleSource.h @@ -41,9 +41,12 @@ class IndicatorTickOrCandleSource : public Indicator { /** * Class constructor. */ - IndicatorTickOrCandleSource(const TS& _iparams, IndicatorBase* _indi_src = NULL, int _indi_mode = 0) - : Indicator(_iparams, _indi_src, _indi_mode) {} - IndicatorTickOrCandleSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} + IndicatorTickOrCandleSource(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorBase* _indi_src = NULL, + int _indi_mode = 0) + : Indicator(_iparams, _idparams, _indi_src, _indi_mode) {} + IndicatorTickOrCandleSource(const TS& _iparams, const IndicatorDataParams& _idparams, + ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) + : Indicator(_iparams, _idparams, _tf) {} IndicatorTickOrCandleSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : Indicator(_itype, _tf, _shift, _name) {} diff --git a/Indicator/IndicatorTickSource.h b/Indicator/IndicatorTickSource.h index ca59b4312..8b47180a5 100644 --- a/Indicator/IndicatorTickSource.h +++ b/Indicator/IndicatorTickSource.h @@ -37,9 +37,11 @@ class IndicatorTickSource : public Indicator { /** * Class constructor. */ - IndicatorTickSource(const TS& _iparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) - : Indicator(_iparams, _indi_src, _indi_mode) {} - IndicatorTickSource(const TS& _iparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(_iparams, _tf) {} + IndicatorTickSource(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, + int _indi_mode = 0) + : Indicator(_iparams, _idparams, _indi_src, _indi_mode) {} + IndicatorTickSource(const TS& _iparams, const IndicatorDataParams& _idparams, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) + : Indicator(_iparams, _idparams, _tf) {} IndicatorTickSource(ENUM_INDICATOR_TYPE _itype, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : Indicator(_itype, _tf, _shift, _name) {} diff --git a/Indicator/tests/classes/IndicatorTickDummy.h b/Indicator/tests/classes/IndicatorTickDummy.h index 823a0d995..dcc473b88 100644 --- a/Indicator/tests/classes/IndicatorTickDummy.h +++ b/Indicator/tests/classes/IndicatorTickDummy.h @@ -35,14 +35,16 @@ // Params for dummy tick-based indicator. struct IndicatorTickDummyParams : IndicatorParams { - IndicatorTickDummyParams() : IndicatorParams(INDI_TICK, 2, TYPE_DOUBLE) {} + IndicatorTickDummyParams() : IndicatorParams(INDI_TICK) {} }; // Dummy tick-based indicator. class IndicatorTickDummy : public IndicatorTick { public: IndicatorTickDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} + : IndicatorTick(INDI_TICK, _tf, _shift, _name) { + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 2); + } string GetName() override { return "IndicatorTickDummy"; } diff --git a/Indicator/tests/classes/IndicatorTickReal.h b/Indicator/tests/classes/IndicatorTickReal.h index 5aa387fd2..fc20d98c5 100644 --- a/Indicator/tests/classes/IndicatorTickReal.h +++ b/Indicator/tests/classes/IndicatorTickReal.h @@ -35,14 +35,16 @@ // Params for real tick-based indicator. struct IndicatorTickRealParams : IndicatorParams { - IndicatorTickRealParams() : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) {} + IndicatorTickRealParams() : IndicatorParams(INDI_TICK) {} }; // Real tick-based indicator. class IndicatorTickReal : public IndicatorTick { public: IndicatorTickReal(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") - : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} + : IndicatorTick(INDI_TICK, _tf, _shift, _name) { + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 3); + } string GetName() override { return "IndicatorTickReal"; } diff --git a/IndicatorBase.h b/IndicatorBase.h index df56648b2..39deaab62 100644 --- a/IndicatorBase.h +++ b/IndicatorBase.h @@ -197,7 +197,7 @@ class IndicatorBase : public Chart { * Gets an indicator's state property value. */ template - T Get(STRUCT_ENUM(IndicatorState, ENUM_INDICATOR_STATE_PROP) _prop) { + T Get(STRUCT_ENUM_INDICATOR_STATE_PROP _prop) { return istate.Get(_prop); } diff --git a/IndicatorData.enum.h b/IndicatorData.enum.h new file mode 100644 index 000000000..12193a557 --- /dev/null +++ b/IndicatorData.enum.h @@ -0,0 +1,54 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2022, 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 + * Includes IndicatorData's enums. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +/* Defines type of source data for */ +enum ENUM_IDATA_SOURCE_TYPE { + IDATA_BUILTIN = 0, // Platform built-in + IDATA_CHART, // Chart calculation + IDATA_ICUSTOM, // iCustom: Custom indicator file + IDATA_ICUSTOM_LEGACY, // iCustom: Custom, legacy, provided by MT indicator file + IDATA_INDICATOR, // OnIndicator: Another indicator as a source of data + IDATA_ONCALCULATE, // OnCalculate: Custom calculation function + IDATA_MATH // Math-based indicator +}; + +/* Defines range value data type for indicator storage. */ +enum ENUM_IDATA_VALUE_RANGE { + IDATA_RANGE_BINARY, // E.g. 0 or 1. + IDATA_RANGE_BITWISE, // Bitwise + IDATA_RANGE_MIXED, + IDATA_RANGE_PRICE, // Values represent price. + IDATA_RANGE_PRICE_DIFF, // Values represent price differences. + IDATA_RANGE_PRICE_ON_SIGNAL, // Values represent price on signal, otherwise zero. + IDATA_RANGE_RANGE, // E.g. 0 to 100. + IDATA_RANGE_UNKNOWN +}; diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 0db969639..12a07a2c9 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -22,6 +22,7 @@ // Includes. #include "IndicatorBase.h" +#include "IndicatorData.enum.h" #include "IndicatorData.struct.h" #include "IndicatorData.struct.serialize.h" #include "IndicatorData.struct.signal.h" @@ -40,9 +41,32 @@ class IndicatorData : public IndicatorBase { BufferStruct idata; DictStruct> indicators; // Indicators list keyed by id. IndicatorCalculateCache cache; - Ref indi_src; // // Indicator used as data source. - bool is_fed; // Whether calc_start_bar is already calculated. - int indi_src_mode; // Mode of source indicator + IndicatorDataParams idparams; // Indicator data params. + Ref indi_src; // Indicator used as data source. + + protected: + /* Protected methods */ + + bool Init() { + ArrayResize(value_storages, idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES))); + if (indi_src.IsSet()) { + // SetDataSource(_indi_src, _indi_mode); + idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE), IDATA_INDICATOR); + } + switch (idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { + case IDATA_BUILTIN: + break; + case IDATA_ICUSTOM: + break; + case IDATA_INDICATOR: + if (indi_src.IsSet() == NULL) { + // Indi_Price* _indi_price = Indi_Price::GetCached(GetSymbol(), GetTf(), iparams.GetShift()); + // SetDataSource(_indi_price, true, PRICE_OPEN); + } + break; + } + return true; + } public: /* Special methods */ @@ -50,13 +74,12 @@ class IndicatorData : public IndicatorBase { /** * Class constructor. */ - IndicatorData(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, string _symbol = NULL) - : indi_src(NULL), is_fed(false), IndicatorBase(_tf, _symbol) {} - - /** - * Class constructor. - */ - IndicatorData(ENUM_TIMEFRAMES_INDEX _tfi, string _symbol = NULL) : IndicatorBase(_tfi, _symbol) {} + IndicatorData(const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) + : idparams(_idparams), indi_src(_indi_src) { + } + IndicatorData(const IndicatorDataParams& _idparams, ENUM_TIMEFRAMES _tf, string _symbol = NULL) + : idparams(_idparams), IndicatorBase(_tf, _symbol) { + } /** * Class deconstructor. @@ -99,6 +122,24 @@ class IndicatorData : public IndicatorBase { IndicatorDataEntry operator[](ENUM_INDICATOR_INDEX _index) { return GetEntry((int)_index); } + /* Getters */ + + /** + * Gets a value from IndicatorDataParams struct. + */ + template + T Get(STRUCT_ENUM_IDATA_PARAM _param) { + return idparams.Get(_param); + } + + /** + * Gets an indicator's state property value. + */ + template + T Get(STRUCT_ENUM_INDICATOR_STATE_PROP _prop) { + return istate.Get(_prop); + } + /* Data methods */ /** @@ -148,7 +189,7 @@ class IndicatorData : public IndicatorBase { int GetBarsCalculated() { int _bars = Bars(GetSymbol(), GetTf()); - if (!is_fed) { + if (!idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IS_FED))) { // Calculating start_bar. for (; calc_start_bar < _bars; ++calc_start_bar) { // Iterating from the oldest or previously iterated. @@ -156,13 +197,13 @@ class IndicatorData : public IndicatorBase { if (_entry.IsValid()) { // From this point we assume that future entries will be all valid. - is_fed = true; + idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IS_FED), true); return _bars - calc_start_bar; } } } - if (!is_fed) { + if (!idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IS_FED))) { Print("Can't find valid bars for ", GetFullName()); return 0; } @@ -202,7 +243,7 @@ class IndicatorData : public IndicatorBase { return _result; } - int GetDataSourceMode() { return indi_src_mode; } + // int GetDataSourceMode() { return indi_src_mode; } /** * Returns currently selected data source without any validation. @@ -280,7 +321,7 @@ class IndicatorData : public IndicatorBase { /** * Sets data source's input mode. */ - void SetDataSourceMode(int _mode) { indi_src_mode = _mode; } + // void SetDataSourceMode(int _mode) { indi_src_mode = _mode; } /* Storage methods */ @@ -411,15 +452,15 @@ class IndicatorData : public IndicatorBase { return; } - if (_source.GetModeCount() > 1 && _target.GetDataSourceMode() == -1) { + if (_source.GetModeCount() > 1 && _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { // Mode must be selected if source indicator has more that one mode. Alert("Warning! ", GetName(), " must select source indicator's mode via SetDataSourceMode(int). Defaulting to mode 0."); - _target.SetDataSourceMode(0); + _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); DebugBreak(); - } else if (_source.GetModeCount() == 1 && _target.GetDataSourceMode() == -1) { - _target.SetDataSourceMode(0); - } else if (_target.GetDataSourceMode() < 0 || _target.GetDataSourceMode() > _source.GetModeCount()) { + } else if (_source.GetModeCount() == 1 && _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { + _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); + } else if (_target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) < 0 || _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) > _source.GetModeCount()) { Alert("Error! ", _target.GetName(), " must select valid source indicator's mode via SetDataSourceMode(int) between 0 and ", _source.GetModeCount(), "."); diff --git a/IndicatorData.struct.h b/IndicatorData.struct.h index d95a547c2..b6f942eb4 100644 --- a/IndicatorData.struct.h +++ b/IndicatorData.struct.h @@ -25,6 +25,9 @@ * Includes IndicatorData's structs. */ +// Defines. +#define STRUCT_ENUM_IDATA_PARAM STRUCT_ENUM(IndicatorDataParams, ENUM_IDATA_PARAM) + // Includes. #include "SerializerNode.enum.h" @@ -383,3 +386,118 @@ struct IndicatorDataEntry { return ToCSV(); } }; + +/* Structure for indicator data parameters. */ +struct IndicatorDataParams { + protected: + /* Struct protected variables */ + bool is_fed; // Whether calc_start_bar is already calculated. + int data_src_mode; // Mode used as input from data source. + int src_id; // Id of the indicator to be used as data source. + int src_mode; // Mode of source indicator + unsigned int max_buffers; // Max buffers to store. + unsigned int max_modes; // Max supported indicator modes (values per entry). + ENUM_DATATYPE dtype; // Type of basic data to store values (DTYPE_DOUBLE, DTYPE_INT). + ENUM_IDATA_SOURCE_TYPE idstype; // Indicator's data source type (e.g. IDATA_BUILTIN, IDATA_ICUSTOM). + ENUM_IDATA_VALUE_RANGE idvrange; // Indicator's range value data type. + public: + /* Struct enumerations */ + enum ENUM_IDATA_PARAM { + IDATA_PARAM_IS_FED = 0, + IDATA_PARAM_DATA_SRC_MODE, + IDATA_PARAM_DTYPE, + IDATA_PARAM_IDSTYPE, + IDATA_PARAM_IDVRANGE, + IDATA_PARAM_MAX_BUFFERS, + IDATA_PARAM_MAX_MODES, + IDATA_PARAM_SRC_ID, + IDATA_PARAM_SRC_MODE, + }; + + public: + /* Special methods */ + // Constructor. + IndicatorDataParams(unsigned int _max_modes = 1, ENUM_DATATYPE _dtype = TYPE_DOUBLE, + ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + ENUM_IDATA_VALUE_RANGE _idvrange = IDATA_RANGE_UNKNOWN, int _data_src_mode = 0) + : data_src_mode(_data_src_mode), + dtype(_dtype), + max_modes(_max_modes), + max_buffers(10), + idstype(_idstype), + idvrange(_idvrange), + is_fed(false), + src_id(-1), + src_mode(-1){}; + // Copy constructor. + IndicatorDataParams(const IndicatorDataParams &_idp) { THIS_REF = _idp; } + // Deconstructor. + ~IndicatorDataParams(){}; + /* Getters */ + template + T Get(STRUCT_ENUM_IDATA_PARAM _param) { + switch (_param) { + case IDATA_PARAM_IS_FED: + return (T)is_fed; + case IDATA_PARAM_DATA_SRC_MODE: + return (T)data_src_mode; + case IDATA_PARAM_DTYPE: + return (T)dtype; + case IDATA_PARAM_IDSTYPE: + return (T)idstype; + case IDATA_PARAM_IDVRANGE: + return (T)idvrange; + case IDATA_PARAM_MAX_BUFFERS: + return (T)max_buffers; + case IDATA_PARAM_MAX_MODES: + return (T)max_modes; + case IDATA_PARAM_SRC_ID: + return (T)src_id; + case IDATA_PARAM_SRC_MODE: + return (T)src_mode; + } + SetUserError(ERR_INVALID_PARAMETER); + return (T)WRONG_VALUE; + } + static IndicatorDataParams GetInstance(unsigned int _max_modes = 1, ENUM_DATATYPE _dtype = TYPE_DOUBLE, + ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + ENUM_IDATA_VALUE_RANGE _idvrange = IDATA_RANGE_UNKNOWN, + int _data_src_mode = 0) { + IndicatorDataParams _instance(_max_modes, _dtype, _idstype, _idvrange, _data_src_mode); + return _instance; + } + /* Setters */ + template + void Set(STRUCT_ENUM_IDATA_PARAM _param, T _value) { + switch (_param) { + case IDATA_PARAM_IS_FED: + is_fed = (bool)_value; + return; + case IDATA_PARAM_DATA_SRC_MODE: + data_src_mode = (int)_value; + return; + case IDATA_PARAM_DTYPE: + dtype = (ENUM_DATATYPE)_value; + return; + case IDATA_PARAM_IDSTYPE: + idstype = (ENUM_IDATA_SOURCE_TYPE)_value; + return; + case IDATA_PARAM_IDVRANGE: + idvrange = (ENUM_IDATA_VALUE_RANGE)_value; + return; + case IDATA_PARAM_MAX_BUFFERS: + max_buffers = (unsigned int)_value; + return; + case IDATA_PARAM_MAX_MODES: + max_modes = (unsigned int)_value; + return; + case IDATA_PARAM_SRC_ID: + src_id = (int)_value; + return; + case IDATA_PARAM_SRC_MODE: + src_mode = (int)_value; + return; + } + SetUserError(ERR_INVALID_PARAMETER); + } +}; diff --git a/IndicatorData.struct.signal.h b/IndicatorData.struct.signal.h index 954e02172..d865e4129 100644 --- a/IndicatorData.struct.signal.h +++ b/IndicatorData.struct.signal.h @@ -33,10 +33,12 @@ // Forward declaration. struct ChartParams; struct IndicatorDataEntry; +struct IndicatorDataParams; struct IndicatorParams; // Includes. -#include "Indicator.struct.h" +//#include "IndicatorData.enum.h" +//#include "Indicator.struct.h" /* Structure for indicator signals. */ struct IndicatorSignal { @@ -56,14 +58,14 @@ struct IndicatorSignal { // Constructors. IndicatorSignal(int _signals = 0) : signals(_signals) {} - IndicatorSignal(ARRAY_REF(IndicatorDataEntry, _data), IndicatorParams &_ip, ChartParams &_cp, int _m1 = 0, + IndicatorSignal(ARRAY_REF(IndicatorDataEntry, _data), IndicatorDataParams &_idp, ChartParams &_cp, int _m1 = 0, int _m2 = 0) : signals(0) { - CalcSignals(_data, _ip, _cp, _m1, _m2); + CalcSignals(_data, _idp, _cp, _m1, _m2); } // Main methods. // Calculate signal values. - void CalcSignals(ARRAY_REF(IndicatorDataEntry, _data), IndicatorParams &_ip, ChartParams &_cp, int _m1 = 0, + void CalcSignals(ARRAY_REF(IndicatorDataEntry, _data), IndicatorDataParams &_idp, ChartParams &_cp, int _m1 = 0, int _m2 = 0) { int _size = ArraySize(_data); // INDICATOR_SIGNAL_CROSSOVER @@ -88,7 +90,7 @@ struct IndicatorSignal { ((_price_w0 - _price_w1) < 0 && (_data[0][_m1] - _data[_size - 1][_m1]) > 0)); // INDICATOR_SIGNAL_GT_PRICE bool _v_gt_p = false; - if (_ip.GetIDataValueRange() == IDATA_RANGE_PRICE) { + if (_idp.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDVRANGE)) == IDATA_RANGE_PRICE) { _v_gt_p = _data[0][_m1] > _price_w0 || _data[0][_m2] > _price_w0; } else { // @todo diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 5e64e4bea..e5af8c561 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -32,9 +32,8 @@ // Structs. struct CandleParams : IndicatorParams { // Struct constructor. - CandleParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorParams(INDI_CANDLE, 1, TYPE_INT) { - SetDataValueRange(IDATA_RANGE_RANGE); - SetDataSourceType(IDATA_BUILTIN); + CandleParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorParams(INDI_CANDLE) { + // SetDataValueRange(IDATA_RANGE_RANGE); shift = _shift; tf = _tf; }; @@ -52,7 +51,8 @@ class Indi_Candle : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Candle(CandleParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Candle(CandleParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_INT, IDATA_BUILTIN), _indi_src){}; Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CANDLE, _tf, _shift){}; @@ -72,7 +72,7 @@ class Indi_Candle : public IndicatorTickOrCandleSource { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); BarOHLC _ohlcs[1]; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // In this mode, price is fetched from chart. _ohlcs[0] = Chart::GetOHLC(_ishift); diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index e0b0e1322..0d0ca49d8 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -32,9 +32,8 @@ // Structs. struct IndiPatternParams : IndicatorParams { // Struct constructor. - IndiPatternParams(int _shift = 0) : IndicatorParams(INDI_PATTERN, 5, TYPE_UINT) { - SetDataValueType(TYPE_UINT); - SetDataValueRange(IDATA_RANGE_BITWISE); + IndiPatternParams(int _shift = 0) : IndicatorParams(INDI_PATTERN) { + // SetDataValueRange(IDATA_RANGE_BITWISE); shift = _shift; }; IndiPatternParams(IndiPatternParams& _params, ENUM_TIMEFRAMES _tf) { @@ -51,7 +50,8 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Pattern(IndiPatternParams& _p, IndicatorData* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pattern(IndiPatternParams& _p, IndicatorData* _indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(5, TYPE_UINT), _indi_src){}; Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PATTERN, _tf, _shift){}; @@ -61,12 +61,13 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int i; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); BarOHLC _ohlcs[8]; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // In this mode, price is fetched from chart. - for (i = 0; i < iparams.GetMaxModes(); ++i) { + for (i = 0; i < _max_modes; ++i) { _ohlcs[i] = Chart::GetOHLC(_ishift + i); if (!_ohlcs[i].IsValid()) { // Return empty entry on invalid candles. @@ -91,7 +92,7 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { return WRONG_VALUE; } - for (i = 0; i < iparams.GetMaxModes(); ++i) { + for (i = 0; i < _max_modes; ++i) { _ohlcs[i].open = GetDataSource().GetValue(PRICE_OPEN, _ishift + i); _ohlcs[i].high = GetDataSource().GetValue(PRICE_HIGH, _ishift + i); _ohlcs[i].low = GetDataSource().GetValue(PRICE_LOW, _ishift + i); diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 820194f95..301d0e78d 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -35,15 +35,10 @@ double iAC(string _symbol, int _tf, int _shift) { // Structs. struct IndiACParams : IndicatorParams { // Struct constructor. - IndiACParams(int _shift = 0) : IndicatorParams(INDI_AC, 1, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiACParams(int _shift = 0) : IndicatorParams(INDI_AC) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Accelerator"); shift = _shift; - switch (idstype) { - case IDATA_ICUSTOM: - SetMaxModes(2); - break; - } }; IndiACParams(IndiACParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; @@ -55,12 +50,31 @@ struct IndiACParams : IndicatorParams { * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ class Indi_AC : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { + case IDATA_ICUSTOM: + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 2); + break; + } + } + public: /** * Class constructor. */ - Indi_AC(IndiACParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; - Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift){}; + Indi_AC(IndiACParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) { + Init(); + }; + Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift) { + Init(); + }; /** * Returns the indicator value. @@ -74,7 +88,8 @@ class Indi_AC : public IndicatorTickOrCandleSource { #ifdef __MQL4__ return ::iAC(_symbol, _tf, _shift); #else // __MQL5__ - int _handle = Object::IsValid(_obj) ? _obj.Get(IndicatorState::INDICATOR_STATE_PROP_HANDLE) : NULL; + int _handle = + Object::IsValid(_obj) ? _obj.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_HANDLE)) : NULL; double _res[]; if (_handle == NULL || _handle == INVALID_HANDLE) { if ((_handle = ::iAC(_symbol, _tf)) == INVALID_HANDLE) { @@ -108,7 +123,7 @@ class Indi_AC : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { IndicatorDataEntryValue _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_AC::iAC(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index 9254326f1..7cd401afc 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -34,8 +34,8 @@ double iAD(string _symbol, int _tf, int _shift) { // Structs. struct IndiADParams : IndicatorParams { // Struct constructor. - IndiADParams(int _shift = 0) : IndicatorParams(INDI_AD, 1, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiADParams(int _shift = 0) : IndicatorParams(INDI_AD) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\AD"); shift = _shift; }; @@ -53,7 +53,8 @@ class Indi_AD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AD(IndiADParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_AD(IndiADParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AD, _tf, _shift) { iparams.SetTf(_tf); }; @@ -104,7 +105,7 @@ class Indi_AD : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_AD::iAD(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 4aeb85518..88c6bbcf5 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -39,17 +39,12 @@ struct IndiADXParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructors. IndiADXParams(unsigned int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0, - ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN) - : period(_period), applied_price(_ap), IndicatorParams(INDI_ADX, FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE) { - SetDataSourceType(_idstype); - SetDataValueRange(IDATA_RANGE_RANGE); + ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) + : period(_period), applied_price(_ap), IndicatorParams(INDI_ADX) { + // SetDataValueRange(IDATA_RANGE_RANGE); SetShift(_shift); - switch (idstype) { - case IDATA_ICUSTOM: - if (custom_indi_name == "") { - SetCustomIndicatorName("Examples\\ADX"); - } - break; + if (custom_indi_name == "") { + SetCustomIndicatorName("Examples\\ADX"); } }; IndiADXParams(IndiADXParams &_params, ENUM_TIMEFRAMES _tf) { @@ -62,12 +57,23 @@ struct IndiADXParams : IndicatorParams { * Implements the Average Directional Movement Index indicator. */ class Indi_ADX : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + void Init() {} + public: /** * Class constructor. */ - Indi_ADX(IndiADXParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} - Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) {} + Indi_ADX(IndiADXParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src) { + Init(); + } + Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -118,7 +124,7 @@ class Indi_ADX : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ADX::iADX(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index 505ce6abd..1f6b41ff8 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -37,13 +37,11 @@ struct IndiADXWParams : IndiADXParams { // Struct constructor. IndiADXWParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0, - ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN) - : IndiADXParams(_period, _ap, _shift, _tf, _idstype) { + ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) + : IndiADXParams(_period, _ap, _shift, _tf) { itype = itype == INDI_NONE || itype == INDI_ADX ? INDI_ADXW : itype; - switch (idstype) { - case IDATA_ICUSTOM: - SetCustomIndicatorName("Examples\\ADXW"); - break; + if (custom_indi_name == "") { + SetCustomIndicatorName("Examples\\ADXW"); } }; IndiADXWParams(IndiADXWParams &_params, ENUM_TIMEFRAMES _tf) { @@ -60,7 +58,8 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ADXW(IndiADXWParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_ADXW(IndiADXWParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src){}; Indi_ADXW(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADXW, _tf, _shift){}; @@ -229,7 +228,7 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN_ADX, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ADXW::iADXWilder(GetSymbol(), GetTf(), GetPeriod(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 506318a04..78873cec7 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -43,16 +43,11 @@ struct IndiAMAParams : IndicatorParams { slow_period(_slow_period), ama_shift(_ama_shift), applied_price(_ap) { - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); // Defaulting to on-indicator mode (will use real ticks from platform via IndicatorTickReal). - SetDataSourceMode(IDATA_INDICATOR); SetShift(_shift); - switch (idstype) { - case IDATA_ICUSTOM: - if (custom_indi_name == "") { - SetCustomIndicatorName("Examples\\AMA"); - } - break; + if (custom_indi_name == "") { + SetCustomIndicatorName("Examples\\AMA"); } }; IndiAMAParams(IndiAMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -70,7 +65,8 @@ class Indi_AMA : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_AMA(IndiAMAParams &_p, IndicatorData *_indi_src = NULL, int _indi_mode = 0) - : IndicatorTickOrCandleSource(_p, _indi_src, _indi_mode) { + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src, + _indi_mode) { iparams.SetIndicatorType(INDI_AMA); }; Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AMA, _tf, _shift){}; @@ -178,7 +174,8 @@ class Indi_AMA : public IndicatorTickOrCandleSource { ExtSlowPeriodEMA, ExtFastPeriodEMA); for (int x = prev_calculated; x < rates_total; ++x) { - Print("price[", x, "] = ", price[x].Get(), ", O = ", iOpen(Symbol(), PERIOD_CURRENT, Bars(Symbol(), PERIOD_CURRENT) - x - 1)); + Print("price[", x, "] = ", price[x].Get(), + ", O = ", iOpen(Symbol(), PERIOD_CURRENT, Bars(Symbol(), PERIOD_CURRENT) - x - 1)); } int i; @@ -225,7 +222,7 @@ class Indi_AMA : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_AMA::iAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFastPeriod(), GetSlowPeriod(), GetAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index 9786aed4d..baae944aa 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -34,11 +34,8 @@ double iAO(string _symbol, int _tf, int _shift) { // Structs. struct IndiAOParams : IndicatorParams { // Struct constructor. - IndiAOParams(int _shift = 0) : IndicatorParams(INDI_AO, 2, TYPE_DOUBLE) { -#ifdef __MQL4__ - max_modes = 1; -#endif - SetDataValueRange(IDATA_RANGE_MIXED); + IndiAOParams(int _shift = 0) : IndicatorParams(INDI_AO) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Awesome_Oscillator"); shift = _shift; }; @@ -52,12 +49,31 @@ struct IndiAOParams : IndicatorParams { * Implements the Awesome oscillator. */ class Indi_AO : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { +#ifdef __MQL4__ + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 1); +#else + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 2); +#endif + } + public: /** * Class constructor. */ - Indi_AO(IndiAOParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; - Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift){}; + Indi_AO(IndiAOParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src) { + Init(); + }; + Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift) { + Init(); + }; /** * Returns the indicator value. @@ -106,7 +122,7 @@ class Indi_AO : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_AO::iAO(GetSymbol(), GetTf(), _ishift, _mode, THIS_PTR); break; diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index a0c578e96..5fb5cf64e 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -30,9 +30,8 @@ struct IndiASIParams : IndicatorParams { unsigned int period; double mpc; // Struct constructor. - IndiASIParams(double _mpc = 300.0, int _shift = 0) - : IndicatorParams(INDI_ASI, 1, TYPE_DOUBLE, PERIOD_CURRENT, IDATA_ONCALCULATE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiASIParams(double _mpc = 300.0, int _shift = 0) : IndicatorParams(INDI_ASI, PERIOD_CURRENT) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ASI"); mpc = _mpc; shift = _shift; @@ -47,12 +46,30 @@ struct IndiASIParams : IndicatorParams { * Implements the Bill Williams' Accelerator/Decelerator oscillator. */ class Indi_ASI : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_BUILTIN) { + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE), IDATA_ONCALCULATE); + } + } + public: /** * Class constructor. */ - Indi_ASI(IndiASIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; - Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift){}; + Indi_ASI(IndiASIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ONCALCULATE), + _indi_src) { + Init(); + }; + Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift) { + Init(); + }; /** * Built-in version of ASI. @@ -168,7 +185,7 @@ class Indi_ASI : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetMaximumPriceChanging() /*]*/, 0, _ishift); diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index e3c8f9e69..fe92820b8 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -35,10 +35,9 @@ double iATR(string _symbol, int _tf, int _period, int _shift) { struct IndiATRParams : IndicatorParams { unsigned int period; // Struct constructors. - IndiATRParams(unsigned int _period = 14, int _shift = 0) - : period(_period), IndicatorParams(INDI_ATR, 1, TYPE_DOUBLE) { + IndiATRParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_ATR) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ATR"); }; IndiATRParams(IndiATRParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_ATR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ATR(IndiATRParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ATR(IndiATRParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ATR, _tf, _shift){}; /** @@ -106,7 +106,7 @@ class Indi_ATR : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ATR::iATR(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index 4908498ee..914745a2d 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -81,9 +81,9 @@ struct IndiAlligatorParams : IndicatorParams { lips_shift(_ls), ma_method(_mm), applied_price(_ap), - IndicatorParams(INDI_ALLIGATOR, FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE) { + IndicatorParams(INDI_ALLIGATOR) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\Alligator"); }; IndiAlligatorParams(IndiAlligatorParams &_params, ENUM_TIMEFRAMES _tf) { @@ -101,7 +101,8 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Alligator(IndiAlligatorParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) {} Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift){}; @@ -172,7 +173,7 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { return GetEntryValue((ENUM_ALLIGATOR_LINE)1, _ishift); } #endif - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Alligator::iAlligator(GetSymbol(), GetTf(), GetJawPeriod(), GetJawShift(), GetTeethPeriod(), GetTeethShift(), GetLipsPeriod(), GetLipsShift(), GetMAMethod(), diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index ec4688adc..b32be9eca 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -30,9 +30,8 @@ struct IndiAppliedPriceParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructor. IndiAppliedPriceParams(ENUM_APPLIED_PRICE _applied_price = PRICE_OPEN, int _shift = 0) - : applied_price(_applied_price), IndicatorParams(INDI_APPLIED_PRICE, 1, TYPE_DOUBLE) { - SetDataSourceType(IDATA_INDICATOR); - SetDataValueRange(IDATA_RANGE_PRICE); + : applied_price(_applied_price), IndicatorParams(INDI_APPLIED_PRICE) { + // SetDataValueRange(IDATA_RANGE_PRICE); shift = _shift; }; IndiAppliedPriceParams(IndiAppliedPriceParams &_params, ENUM_TIMEFRAMES _tf) { @@ -58,7 +57,7 @@ class Indi_AppliedPrice : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_INDICATOR: if (HasDataSource()) { // Future validation of indi_src will check if we set mode for source indicator // (e.g. for applied price of Indi_Price). - iparams.SetDataSourceMode(GetAppliedPrice()); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE), GetAppliedPrice()); _value = Indi_AppliedPrice::iAppliedPriceOnIndicator(GetDataSource(), GetAppliedPrice(), _ishift); } break; @@ -102,7 +101,7 @@ class Indi_AppliedPrice : public IndicatorTickOrCandleSource::IsValidEntry(_entry); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_INDICATOR: if (!HasDataSource()) { GetLogger().Error("Indi_AppliedPrice requires source indicator to be set via SetDataSource()!"); diff --git a/Indicators/Indi_BWMFI.mqh b/Indicators/Indi_BWMFI.mqh index 0d364f139..07965554c 100644 --- a/Indicators/Indi_BWMFI.mqh +++ b/Indicators/Indi_BWMFI.mqh @@ -48,8 +48,7 @@ enum ENUM_MFI_COLOR { struct IndiBWIndiMFIParams : IndicatorParams { ENUM_APPLIED_VOLUME ap; // @todo // Struct constructors. - IndiBWIndiMFIParams(int _shift = 0) : IndicatorParams(INDI_BWMFI, FINAL_BWMFI_BUFFER_ENTRY, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiBWIndiMFIParams(int _shift = 0) : IndicatorParams(INDI_BWMFI) { shift = _shift; SetCustomIndicatorName("Examples\\MarketFacilitationIndex"); }; @@ -63,13 +62,29 @@ struct IndiBWIndiMFIParams : IndicatorParams { * Implements the Market Facilitation Index by Bill Williams indicator. */ class Indi_BWMFI : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_BWMFI_BUFFER_ENTRY); } + public: /** * Class constructor. */ - Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_BWMFI_BUFFER_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) { + Init(); + } Indi_BWMFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_BWMFI, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_BWMFI, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -119,7 +134,7 @@ class Indi_BWMFI : public IndicatorTickOrCandleSource { double _value = EMPTY_VALUE; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_BWMFI::iBWMFI(GetSymbol(), GetTf(), _ishift, (ENUM_BWMFI_BUFFER)_mode, THIS_PTR); break; diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 5368be61e..53b5b9729 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -46,10 +46,9 @@ struct IndiBWZTParams : IndicatorParams { unsigned int second_period; unsigned int sum_period; // Struct constructor. - IndiBWZTParams(int _shift = 0) : IndicatorParams(INDI_BWZT, FINAL_INDI_BWZT_MODE_ENTRY, TYPE_DOUBLE) { + IndiBWZTParams(int _shift = 0) : IndicatorParams(INDI_BWZT) { indi_ac = NULL; indi_ao = NULL; - SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\BW-ZoneTrade"); shift = _shift; }; @@ -63,13 +62,29 @@ struct IndiBWZTParams : IndicatorParams { * Implements the Bill Williams' Zone Trade. */ class Indi_BWZT : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_INDI_BWZT_MODE_ENTRY); } + public: /** * Class constructor. */ - Indi_BWZT(IndiBWZTParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_BWZT(IndiBWZTParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_INDI_BWZT_MODE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) { + Init(); + }; Indi_BWZT(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_BWZT, _tf, _shift){}; + : IndicatorTickOrCandleSource(INDI_BWZT, _tf, _shift) { + Init(); + }; /** * Built-in version of BWZT. @@ -208,7 +223,7 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_BWZT::iBWZT(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index 002a40d08..42a68746e 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -68,13 +68,9 @@ struct IndiBandsParams : IndicatorParams { // Struct constructors. IndiBandsParams(unsigned int _period = 20, double _deviation = 2, int _bshift = 0, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) - : period(_period), - deviation(_deviation), - bshift(_bshift), - applied_price(_ap), - IndicatorParams(INDI_BANDS, FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE) { + : period(_period), deviation(_deviation), bshift(_bshift), applied_price(_ap), IndicatorParams(INDI_BANDS) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\BB"); }; IndiBandsParams(IndiBandsParams &_params, ENUM_TIMEFRAMES _tf) { @@ -87,13 +83,26 @@ struct IndiBandsParams : IndicatorParams { * Implements the Bollinger Bands® indicator. */ class Indi_Bands : public IndicatorTickSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_BANDS_LINE_ENTRY); } + public: /** * Class constructor. */ Indi_Bands(IndiBandsParams &_p, IndicatorData *_indi_src = NULL, int _mode = 0) - : IndicatorTickSource(_p, _indi_src, _mode) {} - Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_BANDS, _tf, _shift) {} + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE), _indi_src, + _mode) { + Init(); + } + Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_BANDS, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -156,7 +165,9 @@ class Indi_Bands : public IndicatorTickSource { int current_shift = _shift + (i - _bands_shift); // Getting current indicator value. _indi_value_buffer[i - _bands_shift] = - _indi[i - _bands_shift].values[_target != NULL ? _target.GetDataSourceMode() : 0].Get(); + _indi[i - _bands_shift] + .values[_target != NULL ? _target.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)) : 0] + .Get(); } // Base band. @@ -242,7 +253,7 @@ class Indi_Bands : public IndicatorTickSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = BAND_BASE, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Bands::iBands(GetSymbol(), GetTf(), GetPeriod(), GetDeviation(), GetBandsShift(), GetAppliedPrice(), (ENUM_BANDS_LINE)_mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index 9d368ddbd..cf0675893 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -37,9 +37,9 @@ struct IndiBearsPowerParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructors. IndiBearsPowerParams(unsigned int _period = 13, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : period(_period), applied_price(_ap), IndicatorParams(INDI_BEARS, 1, TYPE_DOUBLE) { + : period(_period), applied_price(_ap), IndicatorParams(INDI_BEARS) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Bears"); }; IndiBearsPowerParams(IndiBearsPowerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +57,7 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource * Class constructor. */ Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BEARS, _tf, _shift) {} @@ -108,7 +108,7 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = _value = iBearsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index b3ba6ce1d..eec95976a 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -37,9 +37,9 @@ struct IndiBullsPowerParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // (MT5): not used // Struct constructor. IndiBullsPowerParams(unsigned int _period = 13, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : period(_period), applied_price(_ap), IndicatorParams(INDI_BULLS, 1, TYPE_DOUBLE) { + : period(_period), applied_price(_ap), IndicatorParams(INDI_BULLS) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Bulls"); }; IndiBullsPowerParams(IndiBullsPowerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +57,7 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource * Class constructor. */ Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BULLS, _tf, _shift) {} @@ -108,7 +108,7 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = iBullsPower(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index 7e28d50db..b1c2e5e23 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -44,9 +44,9 @@ struct IndiCCIParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructors. IndiCCIParams(unsigned int _period = 14, ENUM_APPLIED_PRICE _applied_price = PRICE_OPEN, int _shift = 0) - : period(_period), applied_price(_applied_price), IndicatorParams(INDI_CCI, 1, TYPE_DOUBLE) { + : period(_period), applied_price(_applied_price), IndicatorParams(INDI_CCI) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CCI"); }; IndiCCIParams(IndiCCIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -63,7 +63,8 @@ class Indi_CCI : public IndicatorTickSource { /** * Class constructor. */ - Indi_CCI(IndiCCIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_CCI(IndiCCIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_CCI, _tf, _shift) {} /** @@ -148,7 +149,7 @@ class Indi_CCI : public IndicatorTickSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // @fixit Somehow shift isn't used neither in MT4 nor MT5. _value = Indi_CCI::iCCI(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), _ishift /* + iparams.shift*/, @@ -162,7 +163,8 @@ class Indi_CCI : public IndicatorTickSource { ValidateSelectedDataSource(); // @fixit Somehow shift isn't used neither in MT4 nor MT5. - _value = Indi_CCI::iCCIOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), GetDataSourceMode(), + _value = Indi_CCI::iCCIOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), _ishift /* + iparams.shift*/); break; } diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index 673e6da66..d8ad2237b 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -36,10 +36,10 @@ struct IndiCHOParams : IndicatorParams { // Struct constructor. IndiCHOParams(int _fast_ma = 3, int _slow_ma = 10, ENUM_MA_METHOD _smooth_method = MODE_EMA, ENUM_APPLIED_VOLUME _input_volume = VOLUME_TICK, int _shift = 0) - : IndicatorParams(INDI_CHAIKIN, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_CHAIKIN) { fast_ma = _fast_ma; input_volume = _input_volume; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CHO"); shift = _shift; slow_ma = _slow_ma; @@ -59,7 +59,8 @@ class Indi_CHO : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHO(IndiCHOParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHO(IndiCHOParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN, _tf, _shift){}; @@ -184,7 +185,7 @@ class Indi_CHO : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_CHO::iChaikin(GetSymbol(), GetTf(), /*[*/ GetSlowMA(), GetFastMA(), GetSmoothMethod(), GetInputVolume() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 3eb6aabd7..1e09c0f97 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -38,9 +38,9 @@ struct IndiCHVParams : IndicatorParams { // Struct constructor. IndiCHVParams(int _smooth_period = 10, int _chv_period = 10, ENUM_CHV_SMOOTH_METHOD _smooth_method = CHV_SMOOTH_METHOD_EMA, int _shift = 0) - : IndicatorParams(INDI_CHAIKIN_V, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_CHAIKIN_V) { chv_period = _chv_period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CHV"); shift = _shift; smooth_method = _smooth_method; @@ -60,7 +60,8 @@ class Indi_CHV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHV(IndiCHVParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_CHV(IndiCHVParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN_V, _tf, _shift){}; @@ -179,7 +180,7 @@ class Indi_CHV : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_CHV::iCHV(GetSymbol(), GetTf(), /*[*/ GetSmoothPeriod(), GetCHVPeriod(), GetSmoothMethod() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index 8fc00a3f8..f1925ac30 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -28,8 +28,8 @@ // Structs. struct IndiColorBarsParams : IndicatorParams { // Struct constructor. - IndiColorBarsParams(int _shift = 0) : IndicatorParams(INDI_COLOR_BARS, 5, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiColorBarsParams(int _shift = 0) : IndicatorParams(INDI_COLOR_BARS) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorBars"); shift = _shift; }; @@ -48,7 +48,7 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ColorBars(IndiColorBarsParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(5, TYPE_DOUBLE), _indi_src){}; Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_BARS, _tf, _shift){}; @@ -127,7 +127,7 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ColorBars::iColorBars(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 87ced8ae1..018dc47b5 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -28,8 +28,8 @@ // Structs. struct IndiColorCandlesDailyParams : IndicatorParams { // Struct constructor. - IndiColorCandlesDailyParams(int _shift = 0) : IndicatorParams(INDI_COLOR_CANDLES_DAILY, 5, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiColorCandlesDailyParams(int _shift = 0) : IndicatorParams(INDI_COLOR_CANDLES_DAILY) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorCandlesDaily"); shift = _shift; }; @@ -48,7 +48,7 @@ class Indi_ColorCandlesDaily : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ColorCandlesDaily::iCCD(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_ColorLine.mqh b/Indicators/Indi_ColorLine.mqh index 4478f7696..509071f5f 100644 --- a/Indicators/Indi_ColorLine.mqh +++ b/Indicators/Indi_ColorLine.mqh @@ -30,9 +30,9 @@ struct IndiColorLineParams : IndicatorParams { IndicatorData *indi_ma; // Struct constructor. - IndiColorLineParams(int _shift = 0) : IndicatorParams(INDI_COLOR_LINE, 2, TYPE_DOUBLE) { + IndiColorLineParams(int _shift = 0) : IndicatorParams(INDI_COLOR_LINE) { indi_ma = NULL; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorLine"); shift = _shift; }; @@ -51,7 +51,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ColorLine(IndiColorLineParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src){}; Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_LINE, _tf, _shift){}; @@ -202,7 +202,7 @@ class Indi_ColorLine : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ColorLine::iColorLine(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index e55cd4e6e..2a6e0ce83 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -32,14 +32,15 @@ struct IndiCustomMovingAverageParams : IndicatorParams { // Struct constructor. IndiCustomMovingAverageParams(int _smooth_period = 13, int _smooth_shift = 0, ENUM_MA_METHOD _smooth_method = MODE_SMMA, int _shift = 0) - : IndicatorParams(INDI_CUSTOM_MOVING_AVG, 1, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); - SetDataSourceType(IDATA_ICUSTOM); + : IndicatorParams(INDI_CUSTOM_MOVING_AVG) { + // SetDataValueRange(IDATA_RANGE_MIXED); + if (custom_indi_name == "") { #ifdef __MQL5__ - SetCustomIndicatorName("Examples\\Custom Moving Average"); + SetCustomIndicatorName("Examples\\Custom Moving Average"); #else - SetCustomIndicatorName("Custom Moving Averages"); + SetCustomIndicatorName("Custom Moving Averages"); #endif + } shift = _shift; smooth_method = _smooth_method; smooth_period = _smooth_period; @@ -60,7 +61,7 @@ class Indi_CustomMovingAverage : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_ICUSTOM: _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetSmoothPeriod(), GetSmoothShift(), GetSmoothMethod() /*]*/, 0, _ishift); diff --git a/Indicators/Indi_DEMA.mqh b/Indicators/Indi_DEMA.mqh index 196122e41..0efcd4261 100644 --- a/Indicators/Indi_DEMA.mqh +++ b/Indicators/Indi_DEMA.mqh @@ -42,16 +42,12 @@ struct IndiDEIndiMAParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructors. IndiDEIndiMAParams(unsigned int _period = 14, int _ma_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : period(_period), ma_shift(_ma_shift), applied_price(_ap), IndicatorParams(INDI_DEMA, 1, TYPE_DOUBLE) { + : period(_period), ma_shift(_ma_shift), applied_price(_ap), IndicatorParams(INDI_DEMA) { SetCustomIndicatorName("Examples\\DEMA"); - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); SetShift(_shift); - switch (idstype) { - case IDATA_ICUSTOM: - if (custom_indi_name == "") { - SetCustomIndicatorName("Examples\\DEMA"); - } - break; + if (custom_indi_name == "") { + SetCustomIndicatorName("Examples\\DEMA"); } }; IndiDEIndiMAParams(IndiDEIndiMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -68,7 +64,8 @@ class Indi_DEMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMA, _tf, _shift) {} @@ -181,7 +178,7 @@ class Indi_DEMA : public IndicatorTickOrCandleSource { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // We're getting DEMA from Price indicator. diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index b62b6516d..0a40549ef 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -35,10 +35,9 @@ double iDeMarker(string _symbol, int _tf, int _period, int _shift) { struct IndiDeMarkerParams : IndicatorParams { unsigned int period; // Struct constructors. - IndiDeMarkerParams(unsigned int _period = 14, int _shift = 0) - : period(_period), IndicatorParams(INDI_DEMARKER, 1, TYPE_DOUBLE) { + IndiDeMarkerParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_DEMARKER) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\DeMarker"); }; IndiDeMarkerParams(IndiDeMarkerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,7 +54,8 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMARKER, _tf, _shift) {} @@ -105,7 +105,7 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = _value = Indi_DeMarker::iDeMarker(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index 4b3f8b57b..034aa91fd 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -33,15 +33,11 @@ // Structs. struct IndiDemoParams : IndicatorParams { // Struct constructors. - IndiDemoParams(int _shift = 0) : IndicatorParams(INDI_DEMO, 1, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiDemoParams(int _shift = 0) : IndicatorParams(INDI_DEMO) { + //// SetDataValueRange(IDATA_RANGE_MIXED); SetShift(_shift); - switch (idstype) { - case IDATA_ICUSTOM: - if (custom_indi_name == "") { - SetCustomIndicatorName("Examples\\Demo"); - } - break; + if (custom_indi_name == "") { + SetCustomIndicatorName("Examples\\Demo"); } }; IndiDemoParams(IndiDemoParams &_params, ENUM_TIMEFRAMES _tf) { @@ -58,7 +54,8 @@ class Indi_Demo : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Demo(IndiDemoParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Demo(IndiDemoParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMO, _tf, _shift){}; diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index c35f6d295..af29271eb 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -32,9 +32,9 @@ struct IndiDetrendedPriceParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructor. IndiDetrendedPriceParams(int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_DETRENDED_PRICE, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_DETRENDED_PRICE) { applied_price = _ap; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\DPO"); period = _period; shift = _shift; @@ -54,7 +54,7 @@ class Indi_DetrendedPrice : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_DetrendedPrice::iDPO(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_Drawer.mqh b/Indicators/Indi_Drawer.mqh index 05258cc71..2d974168d 100644 --- a/Indicators/Indi_Drawer.mqh +++ b/Indicators/Indi_Drawer.mqh @@ -42,7 +42,7 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Drawer(const IndiDrawerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src), redis(true) { + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(0, TYPE_DOUBLE), _indi_src), redis(true) { Init(); } Indi_Drawer(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) @@ -71,15 +71,16 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { virtual bool ExecuteAction(ENUM_INDICATOR_ACTION _action, DataParamEntry &_args[]) { int num_args = ArraySize(_args), i; + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); IndicatorDataEntry entry(num_args - 1); // @fixit Not sure if we should enforce double. // entry.AddFlags(INDI_ENTRY_FLAG_IS_DOUBLE); if (_action == INDI_ACTION_SET_VALUE) { - iparams.SetMaxModes(num_args - 1); + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), num_args - 1); - if (num_args - 1 > iparams.GetMaxModes()) { + if (num_args - 1 > _max_modes) { GetLogger().Error( StringFormat("Too many data for buffers for action %s!", EnumToString(_action), __FUNCTION_LINE__)); return false; @@ -176,7 +177,7 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Drawer::iDrawer(GetSymbol(), GetTf(), _ishift, THIS_PTR); break; @@ -217,5 +218,4 @@ class Indi_Drawer : public IndicatorTickOrCandleSource { istate.is_changed = true; iparams.applied_price = _applied_price; } - }; diff --git a/Indicators/Indi_Drawer.struct.h b/Indicators/Indi_Drawer.struct.h index e868d110e..b9f5f8287 100644 --- a/Indicators/Indi_Drawer.struct.h +++ b/Indicators/Indi_Drawer.struct.h @@ -36,7 +36,7 @@ struct IndiDrawerParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; IndiDrawerParams(unsigned int _period = 10, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE) - : period(_period), applied_price(_ap), IndicatorParams(INDI_DRAWER, 0, TYPE_DOUBLE) { + : period(_period), applied_price(_ap), IndicatorParams(INDI_DRAWER) { // Fetching history data is not yet implemented. SetCustomIndicatorName("Examples\\Drawer"); }; diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index 87624125b..c06cc3c83 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -58,13 +58,9 @@ struct IndiEnvelopesParams : IndicatorParams { ma_method(_ma_method), applied_price(_ap), deviation(_deviation), - IndicatorParams(INDI_ENVELOPES, 2, TYPE_DOUBLE) { -#ifdef __MQL4__ - // There is extra LINE_MAIN in MQL4 for Envelopes. - max_modes = 3; -#endif + IndicatorParams(INDI_ENVELOPES) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\Envelopes"); }; IndiEnvelopesParams(IndiEnvelopesParams &_params, ENUM_TIMEFRAMES _tf) { @@ -77,14 +73,33 @@ struct IndiEnvelopesParams : IndicatorParams { * Implements the Envelopes indicator. */ class Indi_Envelopes : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { +#ifdef __MQL4__ + // There is extra LINE_MAIN in MQL4 for Envelopes. + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 3); +#else + Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 2); +#endif + } + public: /** * Class constructor. */ Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src) { + Init(); + } Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_ENVELOPES, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_ENVELOPES, _tf, _shift) { + Init(); + }; /** * Returns the indicator value. @@ -201,7 +216,7 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Envelopes::iEnvelopes(GetSymbol(), GetTf(), GetMAPeriod(), GetMAMethod(), GetMAShift(), GetAppliedPrice(), GetDeviation(), _mode, _ishift, THIS_PTR); @@ -212,8 +227,9 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { break; case IDATA_INDICATOR: _value = Indi_Envelopes::iEnvelopesOnIndicator(GetCache(), GetDataSource(), GetSymbol(), GetTf(), GetMAPeriod(), - GetMAMethod(), GetDataSourceMode(), GetMAShift(), GetDeviation(), - _mode, _ishift); + GetMAMethod(), + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), + GetMAShift(), GetDeviation(), _mode, _ishift); break; default: SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 96a961c7c..3ebb8c0c5 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -51,9 +51,9 @@ struct IndiForceParams : IndicatorParams { // Struct constructors. IndiForceParams(unsigned int _period = 13, ENUM_MA_METHOD _ma_method = MODE_SMA, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : period(_period), ma_method(_ma_method), applied_price(_ap), IndicatorParams(INDI_FORCE, 1, TYPE_DOUBLE) { + : period(_period), ma_method(_ma_method), applied_price(_ap), IndicatorParams(INDI_FORCE) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Force_Index"); }; IndiForceParams(IndiForceParams &_params, ENUM_TIMEFRAMES _tf) { @@ -71,7 +71,8 @@ class Indi_Force : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Force(IndiForceParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Force(IndiForceParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FORCE, _tf, _shift) {} @@ -121,7 +122,7 @@ class Indi_Force : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Force::iForce(GetSymbol(), GetTf(), GetPeriod(), GetMAMethod(), GetAppliedPrice(), _ishift, THIS_PTR); diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 558c643e9..4a2442c3a 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -33,9 +33,9 @@ struct IndiFrAIndiMAParams : IndicatorParams { // Struct constructor. IndiFrAIndiMAParams(int _period = 14, int _frama_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_FRAMA, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_FRAMA) { frama_shift = _frama_shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\FrAMA"); applied_price = _ap; period = _period; @@ -55,7 +55,8 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FRAMA, _tf, _shift){}; @@ -148,7 +149,7 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_FrAMA::iFrAMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetFRAMAShift(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 01205d3de..2c074b427 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -34,8 +34,7 @@ double iFractals(string _symbol, int _tf, int _mode, int _shift) { // Structs. struct IndiFractalsParams : IndicatorParams { // Struct constructors. - IndiFractalsParams(int _shift = 0) : IndicatorParams(INDI_FRACTALS, FINAL_LO_UP_LINE_ENTRY, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_ARROW); + IndiFractalsParams(int _shift = 0) : IndicatorParams(INDI_FRACTALS) { SetCustomIndicatorName("Examples\\Fractals"); shift = _shift; }; @@ -49,13 +48,29 @@ struct IndiFractalsParams : IndicatorParams { * Implements the Fractals indicator. */ class Indi_Fractals : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_LO_UP_LINE_ENTRY); } + public: /** * Class constructor. */ - Indi_Fractals(IndiFractalsParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Fractals(IndiFractalsParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_LO_UP_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, + IDATA_RANGE_PRICE_ON_SIGNAL), + _indi_src) { + Init(); + } Indi_Fractals(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_FRACTALS, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_FRACTALS, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -105,7 +120,7 @@ class Indi_Fractals : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = _value = Indi_Fractals::iFractals(GetSymbol(), GetTf(), (ENUM_LO_UP_LINE)_mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index a82905673..f2f094df3 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -89,9 +89,8 @@ struct IndiGatorParams : IndicatorParams { lips_shift(_ls), ma_method(_mm), applied_price(_ap), - IndicatorParams(INDI_GATOR, FINAL_GATOR_LINE_HISTOGRAM_ENTRY, TYPE_DOUBLE) { + IndicatorParams(INDI_GATOR) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Gator"); }; IndiGatorParams(IndiGatorParams &_params, ENUM_TIMEFRAMES _tf) { @@ -104,13 +103,29 @@ struct IndiGatorParams : IndicatorParams { * Implements the Gator oscillator. */ class Indi_Gator : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_GATOR_LINE_HISTOGRAM_ENTRY); } + public: /** * Class constructor. */ - Indi_Gator(IndiGatorParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Gator(IndiGatorParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_GATOR_LINE_HISTOGRAM_ENTRY, TYPE_DOUBLE, + IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) { + Init(); + } Indi_Gator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_GATOR, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_GATOR, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -173,7 +188,7 @@ class Indi_Gator : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Gator::iGator(GetSymbol(), GetTf(), GetJawPeriod(), GetJawShift(), GetTeethPeriod(), GetTeethShift(), GetLipsPeriod(), GetLipsShift(), GetMAMethod(), GetAppliedPrice(), diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index ed6581801..01b823e38 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -50,13 +50,14 @@ enum ENUM_HA_MODE { // Structs. struct IndiHeikenAshiParams : IndicatorParams { // Struct constructors. - IndiHeikenAshiParams(int _shift = 0) : IndicatorParams(INDI_HEIKENASHI, FINAL_HA_MODE_ENTRY, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); // @fixit It draws candles! + IndiHeikenAshiParams(int _shift = 0) : IndicatorParams(INDI_HEIKENASHI) { + if (custom_indi_name == "") { #ifdef __MQL4__ - SetCustomIndicatorName("Heiken Ashi"); + SetCustomIndicatorName("Heiken Ashi"); #else - SetCustomIndicatorName("Examples\\Heiken_Ashi"); + SetCustomIndicatorName("Examples\\Heiken_Ashi"); #endif + } shift = _shift; }; IndiHeikenAshiParams(IndiHeikenAshiParams &_params, ENUM_TIMEFRAMES _tf) { @@ -69,14 +70,28 @@ struct IndiHeikenAshiParams : IndicatorParams { * Implements the Heiken-Ashi indicator. */ class Indi_HeikenAshi : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_HA_MODE_ENTRY); } + public: /** * Class constructor. */ Indi_HeikenAshi(IndiHeikenAshiParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(FINAL_HA_MODE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), + _indi_src) { + Init(); + } Indi_HeikenAshi(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_HEIKENASHI, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_HEIKENASHI, _tf, _shift) { + Init(); + } /** * Returns value for iHeikenAshi indicator. @@ -209,7 +224,7 @@ class Indi_HeikenAshi : public IndicatorTickOrCandleSource virtual IndicatorDataEntryValue GetEntryValue(int _mode = HA_OPEN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: #ifdef __MQL4__ // Converting MQL4's enum into MQL5 one, as OnCalculate uses further one. diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 943c0393c..479dd1687 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -69,12 +69,9 @@ struct IndiIchimokuParams : IndicatorParams { unsigned int senkou_span_b; // Struct constructors. IndiIchimokuParams(unsigned int _ts = 9, unsigned int _ks = 26, unsigned int _ss_b = 52, int _shift = 0) - : tenkan_sen(_ts), - kijun_sen(_ks), - senkou_span_b(_ss_b), - IndicatorParams(INDI_ICHIMOKU, FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE) { + : tenkan_sen(_ts), kijun_sen(_ks), senkou_span_b(_ss_b), IndicatorParams(INDI_ICHIMOKU) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Not sure if not mixed. + // SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Not sure if not mixed. SetCustomIndicatorName("Examples\\Ichimoku"); }; IndiIchimokuParams(IndiIchimokuParams &_params, ENUM_TIMEFRAMES _tf) { @@ -87,13 +84,27 @@ struct IndiIchimokuParams : IndicatorParams { * Implements the Ichimoku Kinko Hyo indicator. */ class Indi_Ichimoku : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), FINAL_ICHIMOKU_LINE_ENTRY); } + public: /** * Class constructor. */ - Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) { + Init(); + } Indi_Ichimoku(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) - : IndicatorTickOrCandleSource(INDI_ICHIMOKU, _tf, _shift) {} + : IndicatorTickOrCandleSource(INDI_ICHIMOKU, _tf, _shift) { + Init(); + } /** * Returns the indicator value. @@ -145,7 +156,7 @@ class Indi_Ichimoku : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Ichimoku::iIchimoku(GetSymbol(), GetTf(), GetTenkanSen(), GetKijunSen(), GetSenkouSpanB(), _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index 667d16397..9d366a3c9 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -49,10 +49,8 @@ enum ENUM_INDI_KILLZONES_MODE { struct IndiKillzonesParams : IndicatorParams { ENUM_PP_TYPE method; // Pivot point calculation method. // Struct constructor. - IndiKillzonesParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) - : IndicatorParams(INDI_PIVOT, FINAL_INDI_KILLZONES_MODE_ENTRY, TYPE_FLOAT) { - SetDataValueRange(IDATA_RANGE_MIXED); - SetDataSourceType(IDATA_CHART); + IndiKillzonesParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorParams(INDI_PIVOT) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetShift(_shift); tf = _tf; }; @@ -100,7 +98,9 @@ class Indi_Killzones : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Killzones(IndiKillzonesParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(FINAL_INDI_KILLZONES_MODE_ENTRY, TYPE_FLOAT, IDATA_CHART), _indi_src) { + } Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_KILLZONES, _tf, _shift) {} @@ -111,7 +111,7 @@ class Indi_Killzones : public IndicatorTickOrCandleSource { float _value = FLT_MAX; int _index = (int)_mode / 2; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // Builtin mode not supported. SetUserError(ERR_INVALID_PARAMETER); diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 8c56dbfdf..f5765c1f0 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -56,13 +56,9 @@ struct IndiMAParams : IndicatorParams { // Struct constructors. IndiMAParams(unsigned int _period = 13, int _ma_shift = 10, ENUM_MA_METHOD _ma_method = MODE_SMA, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) - : period(_period), - ma_shift(_ma_shift), - ma_method(_ma_method), - applied_array(_ap), - IndicatorParams(INDI_MA, 1, TYPE_DOUBLE) { + : period(_period), ma_shift(_ma_shift), ma_method(_ma_method), applied_array(_ap), IndicatorParams(INDI_MA) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); + // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\Moving Average"); }; IndiMAParams(IndiMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -79,7 +75,8 @@ class Indi_MA : public IndicatorTickSource { /** * Class constructor. */ - Indi_MA(IndiMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_MA(IndiMAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_MA, _tf, _shift) {} /** @@ -630,7 +627,7 @@ class Indi_MA : public IndicatorTickSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_MA::iMA(GetSymbol(), GetTf(), GetPeriod(), GetMAShift(), GetMAMethod(), GetAppliedPrice(), _ishift, THIS_PTR); @@ -641,10 +638,12 @@ class Indi_MA : public IndicatorTickSource { break; case IDATA_INDICATOR: // Calculating MA value from specified indicator. - _value = Indi_MA::iMAOnIndicator(GetCache(), GetDataSource(), GetDataSourceMode(), GetSymbol(), GetTf(), - GetPeriod(), GetMAShift(), GetMAMethod(), _ishift); + _value = Indi_MA::iMAOnIndicator(GetCache(), GetDataSource(), + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), GetSymbol(), + GetTf(), GetPeriod(), GetMAShift(), GetMAMethod(), _ishift); break; } + return _value; } diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index 08d760125..0e1193ace 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -45,9 +45,9 @@ struct IndiMACDParams : IndicatorParams { ema_slow_period(_esp), signal_period(_sp), applied_price(_ap), - IndicatorParams(INDI_MACD, FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE) { + IndicatorParams(INDI_MACD) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\MACD"); }; IndiMACDParams(IndiMACDParams &_params, ENUM_TIMEFRAMES _tf) { @@ -64,7 +64,9 @@ class Indi_MACD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MACD(IndiMACDParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MACD(IndiMACDParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) {} Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MACD, _tf, _shift) {} @@ -118,7 +120,7 @@ class Indi_MACD : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_MACD::iMACD(GetSymbol(), GetTf(), GetEmaFastPeriod(), GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice(), (ENUM_SIGNAL_LINE)_mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 7e0a70d2c..00f53bfca 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -37,9 +37,9 @@ struct IndiMFIParams : IndicatorParams { ENUM_APPLIED_VOLUME applied_volume; // Ignored in MT4. // Struct constructors. IndiMFIParams(unsigned int _ma_period = 14, ENUM_APPLIED_VOLUME _av = VOLUME_TICK, int _shift = 0) - : ma_period(_ma_period), applied_volume(_av), IndicatorParams(INDI_MFI, 1, TYPE_DOUBLE) { + : ma_period(_ma_period), applied_volume(_av), IndicatorParams(INDI_MFI) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\MFI"); }; IndiMFIParams(IndiMFIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -56,7 +56,8 @@ class Indi_MFI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MFI(IndiMFIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_MFI(IndiMFIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MFI, _tf, _shift) {} /** @@ -114,7 +115,7 @@ class Indi_MFI : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: #ifdef __MQL4__ _value = Indi_MFI::iMFI(GetSymbol(), GetTf(), GetPeriod(), _ishift); diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 6ee2afb9e..70a0958eb 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -33,10 +33,10 @@ struct IndiMassIndexParams : IndicatorParams { int sum_period; // Struct constructor. IndiMassIndexParams(int _period = 9, int _second_period = 9, int _sum_period = 25, int _shift = 0) - : IndicatorParams(INDI_MASS_INDEX, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_MASS_INDEX) { period = _period; second_period = _second_period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\MI"); shift = _shift; sum_period = _sum_period; @@ -56,7 +56,7 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_MassIndex(IndiMassIndexParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MASS_INDEX, _tf, _shift){}; @@ -170,7 +170,7 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_MassIndex::iMI(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetSecondPeriod(), GetSumPeriod() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 8d69ba91f..4f5add12f 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -47,9 +47,9 @@ struct IndiMomentumParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructors. IndiMomentumParams(unsigned int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) - : period(_period), applied_price(_ap), IndicatorParams(INDI_MOMENTUM, 1, TYPE_DOUBLE) { + : period(_period), applied_price(_ap), IndicatorParams(INDI_MOMENTUM) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Momentum"); }; IndiMomentumParams(IndiMomentumParams &_params, ENUM_TIMEFRAMES _tf) { @@ -66,7 +66,8 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Momentum(IndiMomentumParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Momentum(IndiMomentumParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MOMENTUM, _tf, _shift) {} @@ -144,7 +145,7 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // @fixit Somehow shift isn't used neither in MT4 nor MT5. _value = Indi_Momentum::iMomentum(GetSymbol(), GetTf(), GetPeriod(), GetAppliedPrice(), iparams.shift + _ishift, @@ -159,7 +160,8 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { // @fixit Somehow shift isn't used neither in MT4 nor MT5. _value = Indi_Momentum::iMomentumOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetPeriod(), - GetDataSourceMode(), iparams.shift + _shift); + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)), + iparams.shift + _shift); if (iparams.is_draw) { draw.DrawLineTo(StringFormat("%s", GetName()), GetBarTime(iparams.shift + _shift), _value, 1); } diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index abc67491f..ddac4411e 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -36,21 +36,17 @@ struct IndiOBVParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // MT4 only. ENUM_APPLIED_VOLUME applied_volume; // MT5 only. // Struct constructors. - IndiOBVParams(int _shift = 0) : IndicatorParams(INDI_OBV, 1, TYPE_DOUBLE) { + IndiOBVParams(int _shift = 0) : IndicatorParams(INDI_OBV) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\OBV"); applied_price = PRICE_CLOSE; applied_volume = VOLUME_TICK; } - IndiOBVParams(ENUM_APPLIED_VOLUME _av, int _shift = 0) - : applied_volume(_av), IndicatorParams(INDI_OBV, 1, TYPE_DOUBLE) { - max_modes = 1; + IndiOBVParams(ENUM_APPLIED_VOLUME _av, int _shift = 0) : applied_volume(_av), IndicatorParams(INDI_OBV) { shift = _shift; }; - IndiOBVParams(ENUM_APPLIED_PRICE _ap, int _shift = 0) - : applied_price(_ap), IndicatorParams(INDI_OBV, 1, TYPE_DOUBLE) { - max_modes = 1; + IndiOBVParams(ENUM_APPLIED_PRICE _ap, int _shift = 0) : applied_price(_ap), IndicatorParams(INDI_OBV) { shift = _shift; }; IndiOBVParams(IndiOBVParams &_params, ENUM_TIMEFRAMES _tf) { @@ -67,7 +63,8 @@ class Indi_OBV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OBV(IndiOBVParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OBV(IndiOBVParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OBV, _tf, _shift) {} /** @@ -121,7 +118,7 @@ class Indi_OBV : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: #ifdef __MQL4__ _value = Indi_OBV::iOBV(GetSymbol(), GetTf(), GetAppliedPrice(), _ishift); diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index 4ddfbf98f..dc3c8fb8a 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -44,9 +44,9 @@ struct IndiOsMAParams : IndicatorParams { ema_slow_period(_esp), signal_period(_sp), applied_price(_ap), - IndicatorParams(INDI_OSMA, 1, TYPE_DOUBLE) { + IndicatorParams(INDI_OSMA) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\OsMA"); }; IndiOsMAParams(IndiOsMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -63,7 +63,8 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OsMA(IndiOsMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_OsMA(IndiOsMAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OSMA, _tf, _shift) {} @@ -115,7 +116,7 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); double _value = EMPTY_VALUE; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_OsMA::iOsMA(GetSymbol(), GetTf(), GetEmaFastPeriod(), GetEmaSlowPeriod(), GetSignalPeriod(), GetAppliedPrice(), _ishift, THIS_PTR); diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 358d657a3..7bbb9f964 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -30,9 +30,9 @@ struct IndiPivotParams : IndicatorParams { ENUM_PP_TYPE method; // Pivot point calculation method. // Struct constructor. - IndiPivotParams(ENUM_PP_TYPE _method = PP_CLASSIC, int _shift = 0) : IndicatorParams(INDI_PIVOT, 9, TYPE_FLOAT) { + IndiPivotParams(ENUM_PP_TYPE _method = PP_CLASSIC, int _shift = 0) : IndicatorParams(INDI_PIVOT) { method = _method; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; }; IndiPivotParams(IndiPivotParams& _params, ENUM_TIMEFRAMES _tf) { @@ -45,14 +45,26 @@ struct IndiPivotParams : IndicatorParams { * Implements Pivot Detector. */ class Indi_Pivot : public IndicatorTickOrCandleSource { + protected: + /* Protected methods */ + + /** + * Initialize. + */ + void Init() { Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES), 9); } + public: /** * Class constructor. */ - Indi_Pivot(IndiPivotParams& _p, IndicatorData* _indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Pivot(IndiPivotParams& _p, IndicatorData* _indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(9, TYPE_FLOAT), _indi_src) { + Init(); + }; Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PIVOT, _tf, _shift) { iparams.tf = _tf; + Init(); }; /** @@ -72,7 +84,7 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { BarOHLC _ohlc = GetOHLC(_ishift); _entry.timestamp = GetBarTime(_ishift); if (_ohlc.IsValid()) { - _entry.Resize(iparams.GetMaxModes()); + _entry.Resize(Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES))); _ohlc.GetPivots(GetMethod(), _entry.values[0].value.vflt, _entry.values[1].value.vflt, _entry.values[2].value.vflt, _entry.values[3].value.vflt, _entry.values[4].value.vflt, _entry.values[5].value.vflt, _entry.values[6].value.vflt, _entry.values[7].value.vflt, @@ -111,7 +123,7 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { */ virtual bool IsValidEntry(IndicatorDataEntry& _entry) { bool _is_valid = Indicator::IsValidEntry(_entry); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: break; case IDATA_INDICATOR: @@ -139,7 +151,7 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { */ BarOHLC GetOHLC(int _shift = 0) { BarOHLC _ohlc; - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: // In this mode, price is fetched from chart. _ohlc = Chart::GetOHLC(_shift); diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index cefbbcaa3..1717ca999 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -29,10 +29,9 @@ struct IndiPriceChannelParams : IndicatorParams { unsigned int period; // Struct constructor. - IndiPriceChannelParams(unsigned int _period = 22, int _shift = 0) - : IndicatorParams(INDI_PRICE_CHANNEL, 3, TYPE_DOUBLE) { + IndiPriceChannelParams(unsigned int _period = 22, int _shift = 0) : IndicatorParams(INDI_PRICE_CHANNEL) { period = _period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Price_Channel"); shift = _shift; }; @@ -51,7 +50,7 @@ class Indi_PriceChannel : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_PriceChannel::iPriceChannel(GetSymbol(), GetTf(), GetPeriod(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_PriceFeeder.mqh b/Indicators/Indi_PriceFeeder.mqh index 5c79c9bb4..991d764c7 100644 --- a/Indicators/Indi_PriceFeeder.mqh +++ b/Indicators/Indi_PriceFeeder.mqh @@ -32,15 +32,14 @@ struct IndiPriceFeederParams : IndicatorParams { /** * Struct constructor. */ - IndiPriceFeederParams(int _shift = 0) : IndicatorParams(INDI_PRICE_FEEDER, 1, TYPE_DOUBLE) { shift = _shift; } + IndiPriceFeederParams(int _shift = 0) : IndicatorParams(INDI_PRICE_FEEDER) { shift = _shift; } /** * Struct constructor. * * @todo Use more modes (full OHCL). */ - IndiPriceFeederParams(const double& _price_data[], int _total = 0) - : IndicatorParams(INDI_PRICE_FEEDER, 1, TYPE_DOUBLE) { + IndiPriceFeederParams(const double& _price_data[], int _total = 0) : IndicatorParams(INDI_PRICE_FEEDER) { tf = PERIOD_CURRENT; ArrayCopy(price_data, _price_data, 0, 0, _total == 0 ? WHOLE_ARRAY : _total); }; @@ -59,7 +58,7 @@ class Indi_PriceFeeder : public IndicatorTickOrCandleSource::OnTick(); if (iparams.is_draw) { + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); IndicatorDataEntry _entry = GetEntry(0); - for (int i = 0; i < (int)iparams.GetMaxModes(); ++i) { + for (int i = 0; i < _max_modes; ++i) { draw.DrawLineTo(GetName() + "_" + IntegerToString(i), GetBarTime(0), _entry.values[i].GetDbl()); } } diff --git a/Indicators/Indi_PriceVolumeTrend.mqh b/Indicators/Indi_PriceVolumeTrend.mqh index 555e8ed0b..d08ab0d4c 100644 --- a/Indicators/Indi_PriceVolumeTrend.mqh +++ b/Indicators/Indi_PriceVolumeTrend.mqh @@ -30,9 +30,9 @@ struct IndiPriceVolumeTrendParams : IndicatorParams { ENUM_APPLIED_VOLUME applied_volume; // Struct constructor. IndiPriceVolumeTrendParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) - : IndicatorParams(INDI_PRICE_VOLUME_TREND, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_PRICE_VOLUME_TREND) { applied_volume = _applied_volume; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\PVT"); shift = _shift; }; @@ -51,7 +51,7 @@ class Indi_PriceVolumeTrend : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_PriceVolumeTrend::iPVT(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_RS.mqh b/Indicators/Indi_RS.mqh index cad311ddf..4dd4662eb 100644 --- a/Indicators/Indi_RS.mqh +++ b/Indicators/Indi_RS.mqh @@ -30,11 +30,9 @@ struct IndiRSParams : IndicatorParams { ENUM_APPLIED_VOLUME applied_volume; // Struct constructor. - IndiRSParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) - : IndicatorParams(INDI_RS, 2, TYPE_DOUBLE) { + IndiRSParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) : IndicatorParams(INDI_RS) { applied_volume = _applied_volume; - SetDataValueRange(IDATA_RANGE_MIXED); - SetDataSourceType(IDATA_MATH); + // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; }; IndiRSParams(IndiRSParams &_params, ENUM_TIMEFRAMES _tf) { @@ -53,13 +51,16 @@ class Indi_RS : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RS(IndiRSParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) { Init(); }; + Indi_RS(IndiRSParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_MATH), _indi_src) { + Init(); + }; Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RS, _tf, _shift) { Init(); }; void Init() { - if (iparams.GetDataSourceType() == IDATA_MATH) { + if (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE)) == IDATA_MATH) { IndiOHLCParams _iohlc_params(); // @todo Symbol should be already defined for a chart. // @todo If it's not, move initialization to GetValue()/GetEntry() method. @@ -82,7 +83,7 @@ class Indi_RS : public IndicatorTickOrCandleSource { */ virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_MATH: return imath[_mode].Ptr().GetEntryValue(); break; diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index d1f8fd823..6b7e2cc6c 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -51,9 +51,9 @@ struct IndiRSIParams : IndicatorParams { public: IndiRSIParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) - : applied_price(_ap), IndicatorParams(INDI_RSI, 1, TYPE_DOUBLE) { + : applied_price(_ap), IndicatorParams(INDI_RSI) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); // SetDataSourceType(IDATA_ICUSTOM); SetCustomIndicatorName("Examples\\RSI"); SetPeriod(_period); @@ -96,7 +96,8 @@ class Indi_RSI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RSI(IndiRSIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RSI(IndiRSIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RSI, _tf, _shift) {} /** @@ -173,7 +174,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { RSIGainLossData last_data, new_data; unsigned int data_position; double diff; - int _mode = _obj.GetDataSourceMode(); + int _mode = _obj.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)); if (!_obj.aux_data.KeyExists(_bar_time_prev, data_position)) { // No previous SMMA-based average gain and loss. Calculating SMA-based ones. @@ -293,7 +294,7 @@ class Indi_RSI : public IndicatorTickOrCandleSource { double _value = EMPTY_VALUE; double _res[]; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_RSI::iRSI(GetSymbol(), GetTf(), iparams.GetPeriod(), iparams.GetAppliedPrice(), _ishift, THIS_PTR); diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index f51328fa6..a46be0c81 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -35,10 +35,9 @@ double iRVI(string _symbol, int _tf, int _period, int _mode, int _shift) { struct IndiRVIParams : IndicatorParams { unsigned int period; // Struct constructors. - IndiRVIParams(unsigned int _period = 10, int _shift = 0) - : period(_period), IndicatorParams(INDI_RVI, FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE) { + IndiRVIParams(unsigned int _period = 10, int _shift = 0) : period(_period), IndicatorParams(INDI_RVI) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\RVI"); }; IndiRVIParams(IndiRVIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,7 +54,9 @@ class Indi_RVI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RVI(const IndiRVIParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_RVI(const IndiRVIParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) {} Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RVI, _tf, _shift) {} /** @@ -106,7 +107,7 @@ class Indi_RVI : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_RVI::iRVI(GetSymbol(), GetTf(), GetPeriod(), (ENUM_SIGNAL_LINE)_mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index e179dcf5e..7149a2ead 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -31,9 +31,9 @@ struct IndiRateOfChangeParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructor. IndiRateOfChangeParams(int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_RATE_OF_CHANGE, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_RATE_OF_CHANGE) { applied_price = _ap; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ROC"); period = _period; shift = _shift; @@ -53,7 +53,7 @@ class Indi_RateOfChange : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_RateOfChange::iROC(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_SAR.mqh b/Indicators/Indi_SAR.mqh index 626b07abd..495210b67 100644 --- a/Indicators/Indi_SAR.mqh +++ b/Indicators/Indi_SAR.mqh @@ -37,9 +37,9 @@ struct IndiSARParams : IndicatorParams { double max; // Struct constructors. IndiSARParams(double _step = 0.02, double _max = 0.2, int _shift = 0) - : step(_step), max(_max), IndicatorParams(INDI_SAR, 1, TYPE_DOUBLE) { + : step(_step), max(_max), IndicatorParams(INDI_SAR) { shift = _shift; - SetDataValueRange(IDATA_RANGE_PRICE); // @fixit It draws single dot for each bar! + // SetDataValueRange(IDATA_RANGE_PRICE); // @fixit It draws single dot for each bar! SetCustomIndicatorName("Examples\\ParabolicSAR"); }; IndiSARParams(IndiSARParams &_params, ENUM_TIMEFRAMES _tf) { @@ -56,7 +56,8 @@ class Indi_SAR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_SAR(IndiSARParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_SAR(IndiSARParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SAR, _tf, _shift) {} /** @@ -105,7 +106,7 @@ class Indi_SAR : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_SAR::iSAR(GetSymbol(), GetTf(), GetStep(), GetMax(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 3aae93627..bb0b7d62c 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -59,9 +59,9 @@ struct IndiStdDevParams : IndicatorParams { ma_shift(_ma_shift), ma_method(_ma_method), applied_price(_ap), - IndicatorParams(INDI_STDDEV, 1, TYPE_DOUBLE) { + IndicatorParams(INDI_STDDEV) { shift = _shift; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\StdDev"); }; IndiStdDevParams(IndiStdDevParams &_params, ENUM_TIMEFRAMES _tf) { @@ -78,7 +78,8 @@ class Indi_StdDev : public IndicatorTickSource { /** * Class constructor. */ - Indi_StdDev(IndiStdDevParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickSource(_p, _indi_src) {} + Indi_StdDev(IndiStdDevParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_STDDEV, _tf, _shift) {} /** @@ -130,7 +131,7 @@ class Indi_StdDev : public IndicatorTickSource { double _indi_value_buffer[]; double _std_dev; int i; - int _mode = _obj != NULL ? _obj.GetDataSourceMode() : 0; + int _mode = _obj != NULL ? _obj.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_SRC_MODE)) : 0; ArrayResize(_indi_value_buffer, _ma_period); @@ -229,15 +230,14 @@ class Indi_StdDev : public IndicatorTickSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_StdDev::iStdDev(GetSymbol(), GetTf(), GetMAPeriod(), GetMAShift(), GetMAMethod(), GetAppliedPrice(), _ishift, THIS_PTR); break; case IDATA_ICUSTOM: - _value = iCustom(istate.handle, Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), - iparams.GetCustomIndicatorName(), /*[*/ GetMAPeriod(), GetMAShift(), GetMAMethod() /*]*/, 0, - _ishift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.GetCustomIndicatorName(), /*[*/ GetMAPeriod(), + GetMAShift(), GetMAMethod() /*]*/, 0, _ishift); break; case IDATA_INDICATOR: _value = Indi_StdDev::iStdDevOnIndicator(GetDataSource(), GetSymbol(), GetTf(), GetMAPeriod(), GetMAShift(), diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index 2b6a1994a..a12dd8f59 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -48,9 +48,9 @@ struct IndiStochParams : IndicatorParams { slowing(_slowing), ma_method(_ma_method), price_field(_pf), - IndicatorParams(INDI_STOCHASTIC, FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE) { + IndicatorParams(INDI_STOCHASTIC) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\Stochastic"); }; IndiStochParams(IndiStochParams &_params, ENUM_TIMEFRAMES _tf) { @@ -67,7 +67,9 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Stochastic(IndiStochParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_Stochastic(IndiStochParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) {} Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_STOCHASTIC, _tf, _shift) {} @@ -123,7 +125,7 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = LINE_MAIN, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Stochastic::iStochastic(GetSymbol(), GetTf(), GetKPeriod(), GetDPeriod(), GetSlowing(), GetMAMethod(), GetPriceField(), _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 785d0d956..9510bc112 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -33,9 +33,9 @@ struct IndiTEMAParams : IndicatorParams { ENUM_APPLIED_PRICE applied_price; // Struct constructor. IndiTEMAParams(int _period = 14, int _tema_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_TEMA, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_TEMA) { applied_price = _ap; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\TEMA"); period = _period; shift = _shift; @@ -55,7 +55,8 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TEMA(IndiTEMAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TEMA(IndiTEMAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TEMA, _tf, _shift){}; @@ -142,7 +143,7 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_TEMA::iTEMA(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetTEMAShift(), GetAppliedPrice() /*]*/, 0, _ishift, THIS_PTR); diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index e5d521679..6353bd224 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -32,10 +32,9 @@ struct IndiTRIXParams : IndicatorParams { unsigned int tema_shift; ENUM_APPLIED_PRICE applied_price; // Struct constructor. - IndiTRIXParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_TRIX, 1, TYPE_DOUBLE) { + IndiTRIXParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_TRIX) { applied_price = _ap; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\TRIX"); period = _period; shift = _shift; @@ -54,7 +53,8 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TRIX(IndiTRIXParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_TRIX(IndiTRIXParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TRIX, _tf, _shift){}; @@ -141,7 +141,7 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_TRIX::iTriX(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedPrice() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index a6cf9c4b5..de3693ac0 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -42,12 +42,12 @@ struct IndiUltimateOscillatorParams : IndicatorParams { // Struct constructor. IndiUltimateOscillatorParams(int _fast_period = 7, int _middle_period = 14, int _slow_period = 28, int _fast_k = 4, int _middle_k = 2, int _slow_k = 1, int _shift = 0) - : IndicatorParams(INDI_ULTIMATE_OSCILLATOR, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_ULTIMATE_OSCILLATOR) { fast_k = _fast_k; fast_period = _fast_period; middle_k = _middle_k; middle_period = _middle_period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Ultimate_Oscillator"); shift = _shift; slow_k = _slow_k; @@ -68,7 +68,7 @@ class Indi_UltimateOscillator : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_UltimateOscillator::iUO(GetSymbol(), GetTf(), /*[*/ GetFastPeriod(), GetMiddlePeriod(), GetSlowPeriod(), GetFastK(), GetMiddleK(), GetSlowK() /*]*/, _mode, diff --git a/Indicators/Indi_VIDYA.mqh b/Indicators/Indi_VIDYA.mqh index 7ec863d0d..99d4402ee 100644 --- a/Indicators/Indi_VIDYA.mqh +++ b/Indicators/Indi_VIDYA.mqh @@ -35,11 +35,11 @@ struct IndiVIDYAParams : IndicatorParams { // Struct constructor. IndiVIDYAParams(unsigned int _cmo_period = 9, unsigned int _ma_period = 14, unsigned int _vidya_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) - : IndicatorParams(INDI_VIDYA, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_VIDYA) { applied_price = _ap; cmo_period = _cmo_period; ma_period = _ma_period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\VIDYA"); shift = _shift; vidya_shift = _vidya_shift; @@ -58,7 +58,8 @@ class Indi_VIDYA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VIDYA(IndiVIDYAParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VIDYA(IndiVIDYAParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VIDYA, _tf, _shift){}; @@ -164,7 +165,7 @@ class Indi_VIDYA : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_VIDYA::iVIDyA(GetSymbol(), GetTf(), /*[*/ GetCMOPeriod(), GetMAPeriod(), GetVIDYAShift(), GetAppliedPrice() /*]*/, 0, _ishift, THIS_PTR); diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index d06dc12fa..cabb98f4c 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -31,10 +31,10 @@ struct IndiVROCParams : IndicatorParams { ENUM_APPLIED_VOLUME applied_volume; // Struct constructor. IndiVROCParams(unsigned int _period = 25, ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) - : IndicatorParams(INDI_VROC, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_VROC) { applied_volume = _applied_volume; period = _period; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\VROC"); shift = _shift; }; @@ -52,7 +52,8 @@ class Indi_VROC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VROC(IndiVROCParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_VROC(IndiVROCParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; @@ -144,7 +145,7 @@ class Indi_VROC : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_VROC::iVROC(GetSymbol(), GetTf(), /*[*/ GetPeriod(), GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 9a22469f2..3eab3b41e 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -29,12 +29,10 @@ struct IndiVolumesParams : IndicatorParams { ENUM_APPLIED_VOLUME applied_volume; // Struct constructor. - IndiVolumesParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) - : IndicatorParams(INDI_VOLUMES, 2, TYPE_DOUBLE) { + IndiVolumesParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) : IndicatorParams(INDI_VOLUMES) { applied_volume = _applied_volume; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Volumes"); - SetDataSourceType(IDATA_BUILTIN); shift = _shift; }; IndiVolumesParams(IndiVolumesParams &_params, ENUM_TIMEFRAMES _tf) { @@ -51,7 +49,8 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Volumes(IndiVolumesParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Volumes(IndiVolumesParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src){}; Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VOLUMES, _tf, _shift){}; @@ -138,7 +137,7 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_Volumes::iVolumes(GetSymbol(), GetTf(), /*[*/ GetAppliedVolume() /*]*/, _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index a4954ae71..08fa01f9a 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -35,10 +35,9 @@ double iWPR(string _symbol, int _tf, int _period, int _shift) { struct IndiWPRParams : IndicatorParams { unsigned int period; // Struct constructors. - IndiWPRParams(unsigned int _period = 14, int _shift = 0) - : period(_period), IndicatorParams(INDI_WPR, 1, TYPE_DOUBLE) { + IndiWPRParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_WPR) { shift = _shift; - SetDataValueRange(IDATA_RANGE_RANGE); + // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\WPR"); }; IndiWPRParams(IndiWPRParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,7 +54,8 @@ class Indi_WPR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_WPR(IndiWPRParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_WPR(IndiWPRParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WPR, _tf, _shift) {} /** @@ -104,7 +104,7 @@ class Indi_WPR : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_WPR::iWPR(GetSymbol(), GetTf(), GetPeriod(), _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index c46b3c9dc..8bca741a6 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -28,8 +28,8 @@ // Structs. struct IndiWilliamsADParams : IndicatorParams { // Struct constructor. - IndiWilliamsADParams(int _shift = 0) : IndicatorParams(INDI_WILLIAMS_AD, 1, TYPE_DOUBLE) { - SetDataValueRange(IDATA_RANGE_MIXED); + IndiWilliamsADParams(int _shift = 0) : IndicatorParams(INDI_WILLIAMS_AD) { + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\W_AD"); shift = _shift; }; @@ -48,7 +48,7 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource * Class constructor. */ Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, _indi_src){}; + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WILLIAMS_AD, _tf, _shift){}; @@ -138,7 +138,7 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_WilliamsAD::iWAD(GetSymbol(), GetTf(), _mode, _ishift, THIS_PTR); break; diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 316b8a704..603b32d24 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -35,13 +35,10 @@ struct IndiZigZagParams : IndicatorParams { unsigned int backstep; // Struct constructors. IndiZigZagParams(unsigned int _depth = 12, unsigned int _deviation = 5, unsigned int _backstep = 3, int _shift = 0) - : depth(_depth), - deviation(_deviation), - backstep(_backstep), - IndicatorParams(INDI_ZIGZAG, FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE) { + : depth(_depth), deviation(_deviation), backstep(_backstep), IndicatorParams(INDI_ZIGZAG) { shift = _shift; SetCustomIndicatorName("Examples\\ZigZag"); - SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Draws lines between lowest and highest prices! + // SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Draws lines between lowest and highest prices! }; IndiZigZagParams(IndiZigZagParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; @@ -63,7 +60,9 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ZigZag(IndiZigZagParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src) {} + Indi_ZigZag(IndiZigZagParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE), + _indi_src) {} Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ZIGZAG, _tf, _shift) {} @@ -350,7 +349,7 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ZigZag::iZigZag(GetSymbol(), GetTf(), /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index 013de75f9..9642f26c7 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -35,11 +35,11 @@ struct IndiZigZagColorParams : IndicatorParams { // Struct constructor. IndiZigZagColorParams(unsigned int _depth = 12, unsigned int _deviation = 5, unsigned int _backstep = 3, int _shift = 0) - : IndicatorParams(INDI_ZIGZAG_COLOR, 3, TYPE_DOUBLE) { + : IndicatorParams(INDI_ZIGZAG_COLOR) { backstep = _backstep; depth = _depth; deviation = _deviation; - SetDataValueRange(IDATA_RANGE_MIXED); + // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ZigZagColor"); shift = _shift; }; @@ -58,7 +58,7 @@ class Indi_ZigZagColor : public IndicatorTickOrCandleSource= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_BUILTIN: _value = Indi_ZigZagColor::iZigZagColor(GetSymbol(), GetTf(), /*[*/ GetDepth(), GetDeviation(), GetBackstep() /*]*/, (ENUM_ZIGZAG_LINE)_mode, _ishift, THIS_PTR); diff --git a/Indicators/OHLC/Indi_OHLC.mqh b/Indicators/OHLC/Indi_OHLC.mqh index aa8735b59..5a9fd642c 100644 --- a/Indicators/OHLC/Indi_OHLC.mqh +++ b/Indicators/OHLC/Indi_OHLC.mqh @@ -37,9 +37,7 @@ enum ENUM_INDI_OHLC_MODE { // Structs. struct IndiOHLCParams : IndicatorParams { // Struct constructor. - IndiOHLCParams(int _shift = 0) : IndicatorParams(INDI_OHLC, FINAL_INDI_OHLC_MODE_ENTRY, TYPE_DOUBLE) { - SetShift(_shift); - }; + IndiOHLCParams(int _shift = 0) : IndicatorParams(INDI_OHLC) { SetShift(_shift); }; IndiOHLCParams(IndiOHLCParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; tf = _tf; @@ -54,7 +52,9 @@ class Indi_OHLC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OHLC(IndiOHLCParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_OHLC(IndiOHLCParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_INDI_OHLC_MODE_ENTRY, TYPE_DOUBLE), + _indi_src){}; Indi_OHLC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index 53700b731..827381fb6 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -29,8 +29,7 @@ struct PriceIndiParams : IndicatorParams { ENUM_APPLIED_PRICE ap; // Struct constructor. - PriceIndiParams(ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0) - : ap(_ap), IndicatorParams(INDI_PRICE, 1, TYPE_DOUBLE) { + PriceIndiParams(ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0) : ap(_ap), IndicatorParams(INDI_PRICE) { SetShift(_shift); }; PriceIndiParams(PriceIndiParams &_params, ENUM_TIMEFRAMES _tf) { @@ -51,7 +50,8 @@ class Indi_Price : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Price(PriceIndiParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Price(PriceIndiParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; Indi_Price(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Special/Indi_Custom.mqh b/Indicators/Special/Indi_Custom.mqh index 9e6daade7..8b59f5c36 100644 --- a/Indicators/Special/Indi_Custom.mqh +++ b/Indicators/Special/Indi_Custom.mqh @@ -41,9 +41,8 @@ struct IndiCustomParams : public IndicatorParams { DataParamEntry iargs[]; // Struct constructors. - IndiCustomParams(string _filepath = INDI_CUSTOM_PATH, int _shift = 0) : IndicatorParams(INDI_CUSTOM, 1, TYPE_DOUBLE) { + IndiCustomParams(string _filepath = INDI_CUSTOM_PATH, int _shift = 0) : IndicatorParams(INDI_CUSTOM) { custom_indi_name = _filepath; - SetDataSourceType(IDATA_ICUSTOM); } IndiCustomParams(IndiCustomParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; @@ -79,7 +78,8 @@ class Indi_Custom : public Indicator { /** * Class constructor. */ - Indi_Custom(IndiCustomParams &_p, IndicatorData *_indi_src = NULL) : Indicator(_p, _indi_src) {} + Indi_Custom(IndiCustomParams &_p, IndicatorData *_indi_src = NULL) + : Indicator(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ICUSTOM), _indi_src) {} Indi_Custom(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(INDI_CUSTOM, _tf){}; /** @@ -88,19 +88,19 @@ class Indi_Custom : public Indicator { IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_ICUSTOM: switch (iparams.GetParamsSize()) { case 0: - _value = iCustom(istate.handle, Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, _mode, _ishift); break; case 1: - _value = iCustom(istate.handle, Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, iparams.GetParam(1).ToValue(), _mode, _ishift); break; case 2: - _value = iCustom(istate.handle, Get(CHART_PARAM_SYMBOL), Get(CHART_PARAM_TF), + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, iparams.GetParam(1).ToValue(), iparams.GetParam(2).ToValue(), _mode, _ishift); break; diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index 80190ab0e..b0e271bb0 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -43,13 +43,12 @@ struct IndiMathParams : IndicatorParams { IndiMathParams(ENUM_MATH_OP _op = MATH_OP_SUB, unsigned int _mode_1 = 0, unsigned int _mode_2 = 1, unsigned int _shift_1 = 0, unsigned int _shift_2 = 0, int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) - : IndicatorParams(INDI_SPECIAL_MATH, 1, TYPE_DOUBLE) { + : IndicatorParams(INDI_SPECIAL_MATH) { mode_1 = _mode_1; mode_2 = _mode_2; op_builtin = _op; op_mode = MATH_OP_MODE_BUILTIN; - SetDataValueRange(IDATA_RANGE_MIXED); - SetDataSourceType(IDATA_INDICATOR); + // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; shift_1 = _shift_1; shift_2 = _shift_2; @@ -60,14 +59,12 @@ struct IndiMathParams : IndicatorParams { IndiMathParams(MathCustomOpFunction _op, unsigned int _mode_1 = 0, unsigned int _mode_2 = 1, unsigned int _shift_1 = 0, unsigned int _shift_2 = 0, int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) - : IndicatorParams(INDI_SPECIAL_MATH, 1, TYPE_DOUBLE) { - max_modes = 1; + : IndicatorParams(INDI_SPECIAL_MATH) { mode_1 = _mode_1; mode_2 = _mode_2; op_fn = _op; op_mode = MATH_OP_MODE_CUSTOM_FUNCTION; - SetDataValueRange(IDATA_RANGE_MIXED); - SetDataSourceType(IDATA_INDICATOR); + // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; shift_1 = _shift_1; shift_2 = _shift_2; @@ -87,7 +84,8 @@ class Indi_Math : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Math(IndiMathParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource(_p, _indi_src){}; + Indi_Math(IndiMathParams &_p, IndicatorData *_indi_src = NULL) + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_INDICATOR), _indi_src){}; Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SPECIAL_MATH, _tf, _shift){}; @@ -97,7 +95,7 @@ class Indi_Math : public IndicatorTickOrCandleSource { virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = 0) { double _value = EMPTY_VALUE; int _ishift = _shift >= 0 ? _shift : iparams.GetShift(); - switch (iparams.idstype) { + switch (Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDSTYPE))) { case IDATA_INDICATOR: if (!indi_src.IsSet()) { GetLogger().Error( diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 2ea365183..20c0fe906 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -27,7 +27,7 @@ struct IndiTickMtParams : IndicatorParams { string symbol; // Struct constructor. - IndiTickMtParams(string _symbol = NULL, int _shift = 0) : IndicatorParams(INDI_TICK, 3, TYPE_DOUBLE) { + IndiTickMtParams(string _symbol = NULL, int _shift = 0) : IndicatorParams(INDI_TICK) { SetShift(_shift); SetSymbol(_symbol); }; @@ -53,7 +53,7 @@ class Indi_TickMt : public IndicatorTick { * Class constructor. */ Indi_TickMt(IndiTickMtParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTick(_p, _indi_src){}; + : IndicatorTick(_p, IndicatorDataParams::GetInstance(3, TYPE_DOUBLE), _indi_src){}; Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} diff --git a/Strategy.mqh b/Strategy.mqh index 7ec1cde9c..07179d1e2 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -1206,13 +1206,13 @@ class Strategy : public Object { int _count = (int)fmax(fabs(_level), fabs(_method)); int _direction = Order::OrderDirection(_cmd, _mode); Chart *_chart = trade.GetChart(); - IndicatorBase *_indi = GetIndicators().Begin().Value().Ptr(); + IndicatorData *_indi = GetIndicators().Begin().Value().Ptr(); StrategyPriceStop _psm(_method); _psm.SetChartParams(_chart.GetParams()); if (Object::IsValid(_indi)) { - int _ishift = 12; // @todo: Make it dynamic or as variable. - float _value = 0.0f; // @todo - //float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); + int _ishift = 12; // @todo: Make it dynamic or as variable. + float _value = 0.0f; // @todo + // float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); _value = _value + (float)Math::ChangeByPct(fabs(_value - _chart.GetCloseOffer(0)), _level) * _direction; _psm.SetIndicatorPriceValue(_value); /* diff --git a/tests/DrawIndicatorTest.mq5 b/tests/DrawIndicatorTest.mq5 index ef1988fc4..85e54b041 100644 --- a/tests/DrawIndicatorTest.mq5 +++ b/tests/DrawIndicatorTest.mq5 @@ -153,7 +153,7 @@ bool InitIndicators() { bool PrintIndicators(string _prefix = "") { ResetLastError(); for (DictIterator iter = indis.Begin(); iter.IsValid(); ++iter) { - IndicatorBase *_indi = iter.Value(); + IndicatorData *_indi = iter.Value(); if (_indi.Get(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) { PrintFormat("%s: %s: %s", _prefix, _indi.GetName(), _indi.ToString()); } diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index f90c7df14..d37403b81 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -164,7 +164,8 @@ bool InitIndicators() { indis.Push(new Indi_AO()); // Accumulation Swing Index (ASI). - indis.Push(new Indi_ASI()); + IndiASIParams _asi_params; + indis.Push(new Indi_ASI(_asi_params)); // Average True Range (ATR). IndiATRParams atr_params(14); @@ -177,7 +178,7 @@ bool InitIndicators() { // Bollinger Bands over RSI. IndiBandsParams bands_over_rsi_params(20, 2, 0, PRICE_OPEN); - bands_over_rsi_params.SetDataSource(INDI_RSI); + // bands_over_rsi_params.SetDataSource(INDI_RSI); indis.Push(new Indi_Bands(bands_over_rsi_params)); // Bears Power. @@ -220,7 +221,8 @@ bool InitIndicators() { indis.Push(new Indi_Gator(gator_params)); // Heiken Ashi. - indis.Push(new Indi_HeikenAshi()); + IndiHeikenAshiParams _ha_params(); + indis.Push(new Indi_HeikenAshi(_ha_params)); // Ichimoku Kinko Hyo. IndiIchimokuParams ichi_params(9, 26, 52); @@ -262,7 +264,7 @@ bool InitIndicators() { // Relative Strength Index (RSI). IndiRSIParams rsi_over_blt_stddev_params(); - rsi_over_blt_stddev_params.SetDataSource(INDI_STDDEV); + // rsi_over_blt_stddev_params.SetDataSource(INDI_STDDEV); indis.Push(new Indi_RSI(rsi_over_blt_stddev_params)); // Relative Vigor Index (RVI). @@ -396,12 +398,14 @@ bool InitIndicators() { indis.Push(indi_rsi_on_price.Ptr()); // Drawer (socket-based) indicator over RSI over Price. +#ifndef __MQL4__ // @fixme: Fix it for MQL4. IndiDrawerParams drawer_params(14, /*unused*/ PRICE_OPEN); drawer_params.SetDraw(clrBisque, 0); - drawer_params.SetMaxModes(rsi_on_price_params.GetMaxModes()); + // drawer_params.SetMaxModes(rsi_on_price_params.GetMaxModes()); Ref indi_drawer_on_rsi = new Indi_Drawer(drawer_params); indi_drawer_on_rsi.Ptr().SetDataSource(indi_rsi_on_price.Ptr(), PRICE_OPEN); indis.Push(indi_drawer_on_rsi.Ptr()); +#endif // Applied Price over OHCL indicator. IndiAppliedPriceParams applied_price_params(); @@ -429,7 +433,6 @@ bool InitIndicators() { // Original AMA. IndiAMAParams ama_params_orig(); ama_params_orig.SetName("Original AMA to compare"); - ama_params_orig.SetDataSourceType(IDATA_BUILTIN); indis.Push(new Indi_AMA(ama_params_orig)); // Chaikin Oscillator. From 2e47d5cbbc3a5c2b04eaffe02d2f467392dc875c Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 19 Jun 2022 23:54:33 +0100 Subject: [PATCH 78/81] Indicator: Moves GetValuePrice() to IndicatorData Indicators: Fixes indicator data value range types --- Indicator.mqh | 28 -------------- IndicatorData.mqh | 50 ++++++++++++++++++++----- Indicators/Bitwise/Indi_Candle.mqh | 5 ++- Indicators/Bitwise/Indi_Pattern.mqh | 8 ++-- Indicators/Indi_AC.mqh | 4 +- Indicators/Indi_AD.mqh | 4 +- Indicators/Indi_ADX.mqh | 5 ++- Indicators/Indi_AMA.mqh | 6 +-- Indicators/Indi_AO.mqh | 4 +- Indicators/Indi_ASI.mqh | 5 +-- Indicators/Indi_ATR.mqh | 4 +- Indicators/Indi_Alligator.mqh | 7 ++-- Indicators/Indi_AppliedPrice.mqh | 4 +- Indicators/Indi_Bands.mqh | 3 +- Indicators/Indi_BearsPower.mqh | 4 +- Indicators/Indi_BullsPower.mqh | 4 +- Indicators/Indi_CCI.mqh | 4 +- Indicators/Indi_CHO.mqh | 4 +- Indicators/Indi_CHV.mqh | 4 +- Indicators/Indi_ColorBars.mqh | 4 +- Indicators/Indi_ColorCandlesDaily.mqh | 4 +- Indicators/Indi_ColorLine.mqh | 4 +- Indicators/Indi_CustomMovingAverage.mqh | 4 +- Indicators/Indi_DEMA.mqh | 4 +- Indicators/Indi_DeMarker.mqh | 4 +- Indicators/Indi_Demo.mqh | 4 +- Indicators/Indi_DetrendedPrice.mqh | 4 +- Indicators/Indi_Envelopes.mqh | 4 +- Indicators/Indi_Force.mqh | 4 +- Indicators/Indi_FractalAdaptiveMA.mqh | 4 +- Indicators/Indi_Ichimoku.mqh | 3 +- Indicators/Indi_Killzones.mqh | 8 ++-- Indicators/Indi_MA.mqh | 4 +- Indicators/Indi_MACD.mqh | 7 ++-- Indicators/Indi_MFI.mqh | 4 +- Indicators/Indi_MassIndex.mqh | 4 +- Indicators/Indi_Momentum.mqh | 4 +- Indicators/Indi_OBV.mqh | 4 +- Indicators/Indi_OsMA.mqh | 4 +- Indicators/Indi_Pivot.mqh | 4 +- Indicators/Indi_PriceChannel.mqh | 4 +- Indicators/Indi_PriceVolumeTrend.mqh | 4 +- Indicators/Indi_RS.mqh | 4 +- Indicators/Indi_RSI.mqh | 5 +-- Indicators/Indi_RVI.mqh | 7 ++-- Indicators/Indi_RateOfChange.mqh | 4 +- Indicators/Indi_SAR.mqh | 4 +- Indicators/Indi_StdDev.mqh | 4 +- Indicators/Indi_Stochastic.mqh | 7 ++-- Indicators/Indi_TEMA.mqh | 4 +- Indicators/Indi_TRIX.mqh | 4 +- Indicators/Indi_UltimateOscillator.mqh | 4 +- Indicators/Indi_VIDYA.mqh | 4 +- Indicators/Indi_VROC.mqh | 4 +- Indicators/Indi_Volumes.mqh | 4 +- Indicators/Indi_WPR.mqh | 4 +- Indicators/Indi_WilliamsAD.mqh | 4 +- Indicators/Indi_ZigZag.mqh | 5 ++- Indicators/Indi_ZigZagColor.mqh | 5 ++- Indicators/Special/Indi_Custom.mqh | 13 +++---- Indicators/Special/Indi_Math.mqh | 5 +-- Strategy.mqh | 5 +-- 62 files changed, 179 insertions(+), 176 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index b80f40c4e..f44ce84e0 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -584,34 +584,6 @@ class Indicator : public IndicatorData { return median; } - /** - * Returns price corresponding to indicator value for a given shift and mode. - * - * Can be useful for calculating trailing stops based on the indicator. - * - * @return - * Returns price value of the corresponding indicator values. - */ - template - float GetValuePrice(int _shift = 0, int _mode = 0, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL) { - float _price = 0; - if (GetIDataValueRange() != IDATA_RANGE_PRICE) { - _price = (float)GetPrice(_ap, _shift); - } else if (GetIDataValueRange() == IDATA_RANGE_PRICE) { - // When indicator values are the actual prices. - T _values[4]; - if (!CopyValues(_values, 4, _shift, _mode)) { - // When values aren't valid, return 0. - return _price; - } - datetime _bar_time = GetBarTime(_shift); - float _value = 0; - BarOHLC _ohlc(_values, _bar_time); - _price = _ohlc.GetAppliedPrice(_ap); - } - return _price; - } - /** * Returns currently selected data source doing validation. */ diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 12a07a2c9..24e87b092 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -41,8 +41,8 @@ class IndicatorData : public IndicatorBase { BufferStruct idata; DictStruct> indicators; // Indicators list keyed by id. IndicatorCalculateCache cache; - IndicatorDataParams idparams; // Indicator data params. - Ref indi_src; // Indicator used as data source. + IndicatorDataParams idparams; // Indicator data params. + Ref indi_src; // Indicator used as data source. protected: /* Protected methods */ @@ -75,11 +75,9 @@ class IndicatorData : public IndicatorBase { * Class constructor. */ IndicatorData(const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) - : idparams(_idparams), indi_src(_indi_src) { - } + : idparams(_idparams), indi_src(_indi_src) {} IndicatorData(const IndicatorDataParams& _idparams, ENUM_TIMEFRAMES _tf, string _symbol = NULL) - : idparams(_idparams), IndicatorBase(_tf, _symbol) { - } + : idparams(_idparams), IndicatorBase(_tf, _symbol) {} /** * Class deconstructor. @@ -140,6 +138,36 @@ class IndicatorData : public IndicatorBase { return istate.Get(_prop); } + /** + * Returns price corresponding to indicator value for a given shift and mode. + * + * Can be useful for calculating trailing stops based on the indicator. + * + * @return + * Returns price value of the corresponding indicator values. + */ + template + float GetValuePrice(int _shift = 0, int _mode = 0, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL) { + float _price = 0; + ENUM_IDATA_VALUE_RANGE _idvrange = + Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_IDVRANGE)); + if (_idvrange != IDATA_RANGE_PRICE) { + _price = (float)GetPrice(_ap, _shift); + } else if (_idvrange == IDATA_RANGE_PRICE) { + // When indicator values are the actual prices. + T _values[4]; + if (!CopyValues(_values, 4, _shift, _mode)) { + // When values aren't valid, return 0. + return _price; + } + datetime _bar_time = GetBarTime(_shift); + float _value = 0; + BarOHLC _ohlc(_values, _bar_time); + _price = _ohlc.GetAppliedPrice(_ap); + } + return _price; + } + /* Data methods */ /** @@ -452,15 +480,19 @@ class IndicatorData : public IndicatorBase { return; } - if (_source.GetModeCount() > 1 && _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { + if (_source.GetModeCount() > 1 && + _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { // Mode must be selected if source indicator has more that one mode. Alert("Warning! ", GetName(), " must select source indicator's mode via SetDataSourceMode(int). Defaulting to mode 0."); _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); DebugBreak(); - } else if (_source.GetModeCount() == 1 && _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { + } else if (_source.GetModeCount() == 1 && + _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); - } else if (_target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) < 0 || _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) > _source.GetModeCount()) { + } else if (_target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) < 0 || + _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) > + _source.GetModeCount()) { Alert("Error! ", _target.GetName(), " must select valid source indicator's mode via SetDataSourceMode(int) between 0 and ", _source.GetModeCount(), "."); diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index e5af8c561..053710dff 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -33,7 +33,6 @@ struct CandleParams : IndicatorParams { // Struct constructor. CandleParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorParams(INDI_CANDLE) { - // SetDataValueRange(IDATA_RANGE_RANGE); shift = _shift; tf = _tf; }; @@ -52,7 +51,9 @@ class Indi_Candle : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Candle(CandleParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_INT, IDATA_BUILTIN), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_INT, IDATA_BUILTIN, IDATA_RANGE_RANGE), + _indi_src){}; Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CANDLE, _tf, _shift){}; diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index 0d0ca49d8..38641ff40 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -32,10 +32,7 @@ // Structs. struct IndiPatternParams : IndicatorParams { // Struct constructor. - IndiPatternParams(int _shift = 0) : IndicatorParams(INDI_PATTERN) { - // SetDataValueRange(IDATA_RANGE_BITWISE); - shift = _shift; - }; + IndiPatternParams(int _shift = 0) : IndicatorParams(INDI_PATTERN) { shift = _shift; }; IndiPatternParams(IndiPatternParams& _params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; tf = _tf; @@ -51,7 +48,8 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Pattern(IndiPatternParams& _p, IndicatorData* _indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(5, TYPE_UINT), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(5, TYPE_UINT, IDATA_BUILTIN, IDATA_RANGE_BITWISE), _indi_src){}; Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PATTERN, _tf, _shift){}; diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 301d0e78d..78564827f 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -36,7 +36,6 @@ double iAC(string _symbol, int _tf, int _shift) { struct IndiACParams : IndicatorParams { // Struct constructor. IndiACParams(int _shift = 0) : IndicatorParams(INDI_AC) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Accelerator"); shift = _shift; }; @@ -69,7 +68,8 @@ class Indi_AC : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_AC(IndiACParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { Init(); }; Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift) { diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index 7cd401afc..e7e8b1a49 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -35,7 +35,6 @@ double iAD(string _symbol, int _tf, int _shift) { struct IndiADParams : IndicatorParams { // Struct constructor. IndiADParams(int _shift = 0) : IndicatorParams(INDI_AD) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\AD"); shift = _shift; }; @@ -54,7 +53,8 @@ class Indi_AD : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_AD(IndiADParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AD, _tf, _shift) { iparams.SetTf(_tf); }; diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 88c6bbcf5..799763c03 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -41,7 +41,6 @@ struct IndiADXParams : IndicatorParams { IndiADXParams(unsigned int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_TYPICAL, int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : period(_period), applied_price(_ap), IndicatorParams(INDI_ADX) { - // SetDataValueRange(IDATA_RANGE_RANGE); SetShift(_shift); if (custom_indi_name == "") { SetCustomIndicatorName("Examples\\ADX"); @@ -68,7 +67,9 @@ class Indi_ADX : public IndicatorTickOrCandleSource { */ Indi_ADX(IndiADXParams &_p, IndicatorData *_indi_src = NULL) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src) { + _p, + IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), + _indi_src) { Init(); } Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) { diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 78873cec7..51f97d750 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -43,7 +43,6 @@ struct IndiAMAParams : IndicatorParams { slow_period(_slow_period), ama_shift(_ama_shift), applied_price(_ap) { - // SetDataValueRange(IDATA_RANGE_PRICE); // Defaulting to on-indicator mode (will use real ticks from platform via IndicatorTickReal). SetShift(_shift); if (custom_indi_name == "") { @@ -65,8 +64,9 @@ class Indi_AMA : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_AMA(IndiAMAParams &_p, IndicatorData *_indi_src = NULL, int _indi_mode = 0) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src, - _indi_mode) { + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), + _indi_src, _indi_mode) { iparams.SetIndicatorType(INDI_AMA); }; Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AMA, _tf, _shift){}; diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index baae944aa..0cc6b9df5 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -35,7 +35,6 @@ double iAO(string _symbol, int _tf, int _shift) { struct IndiAOParams : IndicatorParams { // Struct constructor. IndiAOParams(int _shift = 0) : IndicatorParams(INDI_AO) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Awesome_Oscillator"); shift = _shift; }; @@ -68,7 +67,8 @@ class Indi_AO : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_AO(IndiAOParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { Init(); }; Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift) { diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 5fb5cf64e..0e0f8ee31 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -31,7 +31,6 @@ struct IndiASIParams : IndicatorParams { double mpc; // Struct constructor. IndiASIParams(double _mpc = 300.0, int _shift = 0) : IndicatorParams(INDI_ASI, PERIOD_CURRENT) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ASI"); mpc = _mpc; shift = _shift; @@ -63,8 +62,8 @@ class Indi_ASI : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ASI(IndiASIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ONCALCULATE), - _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ONCALCULATE, IDATA_RANGE_MIXED), _indi_src) { Init(); }; Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift) { diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index fe92820b8..76fb9014e 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -37,7 +37,6 @@ struct IndiATRParams : IndicatorParams { // Struct constructors. IndiATRParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_ATR) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ATR"); }; IndiATRParams(IndiATRParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_ATR : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ATR(IndiATRParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ATR, _tf, _shift){}; /** diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index 914745a2d..74693c57b 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -83,7 +83,6 @@ struct IndiAlligatorParams : IndicatorParams { applied_price(_ap), IndicatorParams(INDI_ALLIGATOR) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\Alligator"); }; IndiAlligatorParams(IndiAlligatorParams &_params, ENUM_TIMEFRAMES _tf) { @@ -101,8 +100,10 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Alligator(IndiAlligatorParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE), - _indi_src) {} + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), + _indi_src) {} Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift){}; diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index b32be9eca..638d4500c 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -31,7 +31,6 @@ struct IndiAppliedPriceParams : IndicatorParams { // Struct constructor. IndiAppliedPriceParams(ENUM_APPLIED_PRICE _applied_price = PRICE_OPEN, int _shift = 0) : applied_price(_applied_price), IndicatorParams(INDI_APPLIED_PRICE) { - // SetDataValueRange(IDATA_RANGE_PRICE); shift = _shift; }; IndiAppliedPriceParams(IndiAppliedPriceParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_AppliedPrice : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Bands(IndiBandsParams &_p, IndicatorData *_indi_src = NULL, int _mode = 0) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE), _indi_src, + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src, _mode) { Init(); } diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index cf0675893..de0318428 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -39,7 +39,6 @@ struct IndiBearsPowerParams : IndicatorParams { IndiBearsPowerParams(unsigned int _period = 13, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : period(_period), applied_price(_ap), IndicatorParams(INDI_BEARS) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Bears"); }; IndiBearsPowerParams(IndiBearsPowerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource * Class constructor. */ Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BEARS, _tf, _shift) {} diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index eec95976a..14a8884ed 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -39,7 +39,6 @@ struct IndiBullsPowerParams : IndicatorParams { IndiBullsPowerParams(unsigned int _period = 13, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : period(_period), applied_price(_ap), IndicatorParams(INDI_BULLS) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Bulls"); }; IndiBullsPowerParams(IndiBullsPowerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource * Class constructor. */ Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BULLS, _tf, _shift) {} diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index b1c2e5e23..cf7f2bfcd 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -46,7 +46,6 @@ struct IndiCCIParams : IndicatorParams { IndiCCIParams(unsigned int _period = 14, ENUM_APPLIED_PRICE _applied_price = PRICE_OPEN, int _shift = 0) : period(_period), applied_price(_applied_price), IndicatorParams(INDI_CCI) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CCI"); }; IndiCCIParams(IndiCCIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -64,7 +63,8 @@ class Indi_CCI : public IndicatorTickSource { * Class constructor. */ Indi_CCI(IndiCCIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) {} Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_CCI, _tf, _shift) {} /** diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index d8ad2237b..f5f48157e 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -39,7 +39,6 @@ struct IndiCHOParams : IndicatorParams { : IndicatorParams(INDI_CHAIKIN) { fast_ma = _fast_ma; input_volume = _input_volume; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CHO"); shift = _shift; slow_ma = _slow_ma; @@ -60,7 +59,8 @@ class Indi_CHO : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_CHO(IndiCHOParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN, _tf, _shift){}; diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 1e09c0f97..7b8119289 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -40,7 +40,6 @@ struct IndiCHVParams : IndicatorParams { ENUM_CHV_SMOOTH_METHOD _smooth_method = CHV_SMOOTH_METHOD_EMA, int _shift = 0) : IndicatorParams(INDI_CHAIKIN_V) { chv_period = _chv_period; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\CHV"); shift = _shift; smooth_method = _smooth_method; @@ -61,7 +60,8 @@ class Indi_CHV : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_CHV(IndiCHVParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN_V, _tf, _shift){}; diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index f1925ac30..78082f8a5 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -29,7 +29,6 @@ struct IndiColorBarsParams : IndicatorParams { // Struct constructor. IndiColorBarsParams(int _shift = 0) : IndicatorParams(INDI_COLOR_BARS) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorBars"); shift = _shift; }; @@ -48,7 +47,8 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ColorBars(IndiColorBarsParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(5, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(5, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_BARS, _tf, _shift){}; diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index 018dc47b5..e47528dac 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -29,7 +29,6 @@ struct IndiColorCandlesDailyParams : IndicatorParams { // Struct constructor. IndiColorCandlesDailyParams(int _shift = 0) : IndicatorParams(INDI_COLOR_CANDLES_DAILY) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ColorCandlesDaily"); shift = _shift; }; @@ -48,7 +47,8 @@ class Indi_ColorCandlesDaily : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ColorLine(IndiColorLineParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_LINE, _tf, _shift){}; diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index 2a6e0ce83..8db902680 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -33,7 +33,6 @@ struct IndiCustomMovingAverageParams : IndicatorParams { IndiCustomMovingAverageParams(int _smooth_period = 13, int _smooth_shift = 0, ENUM_MA_METHOD _smooth_method = MODE_SMMA, int _shift = 0) : IndicatorParams(INDI_CUSTOM_MOVING_AVG) { - // SetDataValueRange(IDATA_RANGE_MIXED); if (custom_indi_name == "") { #ifdef __MQL5__ SetCustomIndicatorName("Examples\\Custom Moving Average"); @@ -61,7 +60,8 @@ class Indi_CustomMovingAverage : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) {} Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMA, _tf, _shift) {} diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index 0a40549ef..e45f2420b 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -37,7 +37,6 @@ struct IndiDeMarkerParams : IndicatorParams { // Struct constructors. IndiDeMarkerParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_DEMARKER) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\DeMarker"); }; IndiDeMarkerParams(IndiDeMarkerParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,7 +54,8 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMARKER, _tf, _shift) {} diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index 034aa91fd..3a561463a 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -34,7 +34,6 @@ struct IndiDemoParams : IndicatorParams { // Struct constructors. IndiDemoParams(int _shift = 0) : IndicatorParams(INDI_DEMO) { - //// SetDataValueRange(IDATA_RANGE_MIXED); SetShift(_shift); if (custom_indi_name == "") { SetCustomIndicatorName("Examples\\Demo"); @@ -55,7 +54,8 @@ class Indi_Demo : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Demo(IndiDemoParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMO, _tf, _shift){}; diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index af29271eb..9767ffe23 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -34,7 +34,6 @@ struct IndiDetrendedPriceParams : IndicatorParams { IndiDetrendedPriceParams(int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_DETRENDED_PRICE) { applied_price = _ap; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\DPO"); period = _period; shift = _shift; @@ -54,7 +53,8 @@ class Indi_DetrendedPrice : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE), _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) { Init(); } Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 3ebb8c0c5..83476a19b 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -53,7 +53,6 @@ struct IndiForceParams : IndicatorParams { int _shift = 0) : period(_period), ma_method(_ma_method), applied_price(_ap), IndicatorParams(INDI_FORCE) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Force_Index"); }; IndiForceParams(IndiForceParams &_params, ENUM_TIMEFRAMES _tf) { @@ -72,7 +71,8 @@ class Indi_Force : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Force(IndiForceParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FORCE, _tf, _shift) {} diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index 4a2442c3a..cf0751685 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -35,7 +35,6 @@ struct IndiFrAIndiMAParams : IndicatorParams { IndiFrAIndiMAParams(int _period = 14, int _frama_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_FRAMA) { frama_shift = _frama_shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\FrAMA"); applied_price = _ap; period = _period; @@ -56,7 +55,8 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FRAMA, _tf, _shift){}; diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 479dd1687..2e2683ced 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -71,7 +71,6 @@ struct IndiIchimokuParams : IndicatorParams { IndiIchimokuParams(unsigned int _ts = 9, unsigned int _ks = 26, unsigned int _ss_b = 52, int _shift = 0) : tenkan_sen(_ts), kijun_sen(_ks), senkou_span_b(_ss_b), IndicatorParams(INDI_ICHIMOKU) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Not sure if not mixed. SetCustomIndicatorName("Examples\\Ichimoku"); }; IndiIchimokuParams(IndiIchimokuParams &_params, ENUM_TIMEFRAMES _tf) { @@ -97,7 +96,7 @@ class Indi_Ichimoku : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE), + : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) { Init(); } diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index 9d366a3c9..d8a8aada2 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -50,7 +50,6 @@ struct IndiKillzonesParams : IndicatorParams { ENUM_PP_TYPE method; // Pivot point calculation method. // Struct constructor. IndiKillzonesParams(int _shift = 0, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorParams(INDI_PIVOT) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetShift(_shift); tf = _tf; }; @@ -98,9 +97,10 @@ class Indi_Killzones : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Killzones(IndiKillzonesParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(FINAL_INDI_KILLZONES_MODE_ENTRY, TYPE_FLOAT, IDATA_CHART), _indi_src) { - } + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_KILLZONES_MODE_ENTRY, TYPE_FLOAT, + IDATA_CHART, IDATA_RANGE_PRICE), + _indi_src) {} Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_KILLZONES, _tf, _shift) {} diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index f5765c1f0..89a23e6e0 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -58,7 +58,6 @@ struct IndiMAParams : IndicatorParams { ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) : period(_period), ma_shift(_ma_shift), ma_method(_ma_method), applied_array(_ap), IndicatorParams(INDI_MA) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_PRICE); SetCustomIndicatorName("Examples\\Moving Average"); }; IndiMAParams(IndiMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -76,7 +75,8 @@ class Indi_MA : public IndicatorTickSource { * Class constructor. */ Indi_MA(IndiMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), + _indi_src) {} Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_MA, _tf, _shift) {} /** diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index 0e1193ace..d8c6da7f7 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -47,7 +47,6 @@ struct IndiMACDParams : IndicatorParams { applied_price(_ap), IndicatorParams(INDI_MACD) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\MACD"); }; IndiMACDParams(IndiMACDParams &_params, ENUM_TIMEFRAMES _tf) { @@ -65,8 +64,10 @@ class Indi_MACD : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_MACD(IndiMACDParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), - _indi_src) {} + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), + _indi_src) {} Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MACD, _tf, _shift) {} diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 00f53bfca..238334d19 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -39,7 +39,6 @@ struct IndiMFIParams : IndicatorParams { IndiMFIParams(unsigned int _ma_period = 14, ENUM_APPLIED_VOLUME _av = VOLUME_TICK, int _shift = 0) : ma_period(_ma_period), applied_volume(_av), IndicatorParams(INDI_MFI) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\MFI"); }; IndiMFIParams(IndiMFIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -57,7 +56,8 @@ class Indi_MFI : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_MFI(IndiMFIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MFI, _tf, _shift) {} /** diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 70a0958eb..95cf7f4e6 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -36,7 +36,6 @@ struct IndiMassIndexParams : IndicatorParams { : IndicatorParams(INDI_MASS_INDEX) { period = _period; second_period = _second_period; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\MI"); shift = _shift; sum_period = _sum_period; @@ -56,7 +55,8 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_MassIndex(IndiMassIndexParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MASS_INDEX, _tf, _shift){}; diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 4f5add12f..0f13c5904 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -49,7 +49,6 @@ struct IndiMomentumParams : IndicatorParams { IndiMomentumParams(unsigned int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) : period(_period), applied_price(_ap), IndicatorParams(INDI_MOMENTUM) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Momentum"); }; IndiMomentumParams(IndiMomentumParams &_params, ENUM_TIMEFRAMES _tf) { @@ -67,7 +66,8 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Momentum(IndiMomentumParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MOMENTUM, _tf, _shift) {} diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index ddac4411e..38ef7d284 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -38,7 +38,6 @@ struct IndiOBVParams : IndicatorParams { // Struct constructors. IndiOBVParams(int _shift = 0) : IndicatorParams(INDI_OBV) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\OBV"); applied_price = PRICE_CLOSE; applied_volume = VOLUME_TICK; @@ -64,7 +63,8 @@ class Indi_OBV : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_OBV(IndiOBVParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OBV, _tf, _shift) {} /** diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index dc3c8fb8a..faadb39b6 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -46,7 +46,6 @@ struct IndiOsMAParams : IndicatorParams { applied_price(_ap), IndicatorParams(INDI_OSMA) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\OsMA"); }; IndiOsMAParams(IndiOsMAParams &_params, ENUM_TIMEFRAMES _tf) { @@ -64,7 +63,8 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_OsMA(IndiOsMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OSMA, _tf, _shift) {} diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 7bbb9f964..6dc65fbd9 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -32,7 +32,6 @@ struct IndiPivotParams : IndicatorParams { // Struct constructor. IndiPivotParams(ENUM_PP_TYPE _method = PP_CLASSIC, int _shift = 0) : IndicatorParams(INDI_PIVOT) { method = _method; - // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; }; IndiPivotParams(IndiPivotParams& _params, ENUM_TIMEFRAMES _tf) { @@ -58,7 +57,8 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Pivot(IndiPivotParams& _p, IndicatorData* _indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(9, TYPE_FLOAT), _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(9, TYPE_FLOAT, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { Init(); }; Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index 1717ca999..23de9a63b 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -31,7 +31,6 @@ struct IndiPriceChannelParams : IndicatorParams { // Struct constructor. IndiPriceChannelParams(unsigned int _period = 22, int _shift = 0) : IndicatorParams(INDI_PRICE_CHANNEL) { period = _period; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Price_Channel"); shift = _shift; }; @@ -50,7 +49,8 @@ class Indi_PriceChannel : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_RS(IndiRSParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_MATH), _indi_src) { + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_MATH, IDATA_RANGE_PRICE_DIFF), _indi_src) { Init(); }; Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RS, _tf, _shift) { diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index 6b7e2cc6c..1ccce509e 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -53,8 +53,6 @@ struct IndiRSIParams : IndicatorParams { IndiRSIParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_OPEN, int _shift = 0) : applied_price(_ap), IndicatorParams(INDI_RSI) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); - // SetDataSourceType(IDATA_ICUSTOM); SetCustomIndicatorName("Examples\\RSI"); SetPeriod(_period); }; @@ -97,7 +95,8 @@ class Indi_RSI : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_RSI(IndiRSIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RSI, _tf, _shift) {} /** diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index a46be0c81..c9435bbee 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -37,7 +37,6 @@ struct IndiRVIParams : IndicatorParams { // Struct constructors. IndiRVIParams(unsigned int _period = 10, int _shift = 0) : period(_period), IndicatorParams(INDI_RVI) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\RVI"); }; IndiRVIParams(IndiRVIParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,8 +54,10 @@ class Indi_RVI : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_RVI(const IndiRVIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), - _indi_src) {} + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) {} Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RVI, _tf, _shift) {} /** diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index 7149a2ead..aa7c8dcd1 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -33,7 +33,6 @@ struct IndiRateOfChangeParams : IndicatorParams { IndiRateOfChangeParams(int _period = 12, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_RATE_OF_CHANGE) { applied_price = _ap; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ROC"); period = _period; shift = _shift; @@ -53,7 +52,8 @@ class Indi_RateOfChange : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_SAR(IndiSARParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) {} Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SAR, _tf, _shift) {} /** diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index bb0b7d62c..0c9ff8cd1 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -61,7 +61,6 @@ struct IndiStdDevParams : IndicatorParams { applied_price(_ap), IndicatorParams(INDI_STDDEV) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\StdDev"); }; IndiStdDevParams(IndiStdDevParams &_params, ENUM_TIMEFRAMES _tf) { @@ -79,7 +78,8 @@ class Indi_StdDev : public IndicatorTickSource { * Class constructor. */ Indi_StdDev(IndiStdDevParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), + _indi_src) {} Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_STDDEV, _tf, _shift) {} /** diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index a12dd8f59..1851dfe63 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -50,7 +50,6 @@ struct IndiStochParams : IndicatorParams { price_field(_pf), IndicatorParams(INDI_STOCHASTIC) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\Stochastic"); }; IndiStochParams(IndiStochParams &_params, ENUM_TIMEFRAMES _tf) { @@ -68,8 +67,10 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Stochastic(IndiStochParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE), - _indi_src) {} + : IndicatorTickOrCandleSource( + _p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), + _indi_src) {} Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_STOCHASTIC, _tf, _shift) {} diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 9510bc112..597139639 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -35,7 +35,6 @@ struct IndiTEMAParams : IndicatorParams { IndiTEMAParams(int _period = 14, int _tema_shift = 0, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_TEMA) { applied_price = _ap; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\TEMA"); period = _period; shift = _shift; @@ -56,7 +55,8 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_TEMA(IndiTEMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TEMA, _tf, _shift){}; diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index 6353bd224..862d267e2 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -34,7 +34,6 @@ struct IndiTRIXParams : IndicatorParams { // Struct constructor. IndiTRIXParams(int _period = 14, ENUM_APPLIED_PRICE _ap = PRICE_CLOSE, int _shift = 0) : IndicatorParams(INDI_TRIX) { applied_price = _ap; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\TRIX"); period = _period; shift = _shift; @@ -54,7 +53,8 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_TRIX(IndiTRIXParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TRIX, _tf, _shift){}; diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index de3693ac0..33b6c2576 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -47,7 +47,6 @@ struct IndiUltimateOscillatorParams : IndicatorParams { fast_period = _fast_period; middle_k = _middle_k; middle_period = _middle_period; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Ultimate_Oscillator"); shift = _shift; slow_k = _slow_k; @@ -68,7 +67,8 @@ class Indi_UltimateOscillator : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_VIDYA(IndiVIDYAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VIDYA, _tf, _shift){}; diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index cabb98f4c..468ec8b53 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -34,7 +34,6 @@ struct IndiVROCParams : IndicatorParams { : IndicatorParams(INDI_VROC) { applied_volume = _applied_volume; period = _period; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\VROC"); shift = _shift; }; @@ -53,7 +52,8 @@ class Indi_VROC : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_VROC(IndiVROCParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 3eab3b41e..0db8a7745 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -31,7 +31,6 @@ struct IndiVolumesParams : IndicatorParams { // Struct constructor. IndiVolumesParams(ENUM_APPLIED_VOLUME _applied_volume = VOLUME_TICK, int _shift = 0) : IndicatorParams(INDI_VOLUMES) { applied_volume = _applied_volume; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\Volumes"); shift = _shift; }; @@ -50,7 +49,8 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Volumes(IndiVolumesParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VOLUMES, _tf, _shift){}; diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index 08fa01f9a..1d872a618 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -37,7 +37,6 @@ struct IndiWPRParams : IndicatorParams { // Struct constructors. IndiWPRParams(unsigned int _period = 14, int _shift = 0) : period(_period), IndicatorParams(INDI_WPR) { shift = _shift; - // SetDataValueRange(IDATA_RANGE_RANGE); SetCustomIndicatorName("Examples\\WPR"); }; IndiWPRParams(IndiWPRParams &_params, ENUM_TIMEFRAMES _tf) { @@ -55,7 +54,8 @@ class Indi_WPR : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_WPR(IndiWPRParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src) {} + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WPR, _tf, _shift) {} /** diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 8bca741a6..43e8cc399 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -29,7 +29,6 @@ struct IndiWilliamsADParams : IndicatorParams { // Struct constructor. IndiWilliamsADParams(int _shift = 0) : IndicatorParams(INDI_WILLIAMS_AD) { - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\W_AD"); shift = _shift; }; @@ -48,7 +47,8 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource * Class constructor. */ Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WILLIAMS_AD, _tf, _shift){}; diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 603b32d24..59f7df91e 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -38,7 +38,6 @@ struct IndiZigZagParams : IndicatorParams { : depth(_depth), deviation(_deviation), backstep(_backstep), IndicatorParams(INDI_ZIGZAG) { shift = _shift; SetCustomIndicatorName("Examples\\ZigZag"); - // SetDataValueRange(IDATA_RANGE_PRICE); // @fixit Draws lines between lowest and highest prices! }; IndiZigZagParams(IndiZigZagParams &_params, ENUM_TIMEFRAMES _tf) { THIS_REF = _params; @@ -61,7 +60,9 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_ZigZag(IndiZigZagParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE), + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE, + IDATA_BUILTIN, IDATA_RANGE_PRICE_ON_SIGNAL), _indi_src) {} Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ZIGZAG, _tf, _shift) {} diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index 9642f26c7..cad1f31db 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -39,7 +39,6 @@ struct IndiZigZagColorParams : IndicatorParams { backstep = _backstep; depth = _depth; deviation = _deviation; - // SetDataValueRange(IDATA_RANGE_MIXED); SetCustomIndicatorName("Examples\\ZigZagColor"); shift = _shift; }; @@ -58,7 +57,9 @@ class Indi_ZigZagColor : public IndicatorTickOrCandleSource { case IDATA_ICUSTOM: switch (iparams.GetParamsSize()) { case 0: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), - iparams.custom_indi_name, _mode, _ishift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, _mode, _ishift); break; case 1: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), - iparams.custom_indi_name, iparams.GetParam(1).ToValue(), _mode, _ishift); + _value = iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, + iparams.GetParam(1).ToValue(), _mode, _ishift); break; case 2: - _value = iCustom(istate.handle, GetSymbol(), GetTf(), - iparams.custom_indi_name, iparams.GetParam(1).ToValue(), - iparams.GetParam(2).ToValue(), _mode, _ishift); + _value = + iCustom(istate.handle, GetSymbol(), GetTf(), iparams.custom_indi_name, + iparams.GetParam(1).ToValue(), iparams.GetParam(2).ToValue(), _mode, _ishift); break; } break; diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index b0e271bb0..4ed2aad41 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -48,7 +48,6 @@ struct IndiMathParams : IndicatorParams { mode_2 = _mode_2; op_builtin = _op; op_mode = MATH_OP_MODE_BUILTIN; - // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; shift_1 = _shift_1; shift_2 = _shift_2; @@ -64,7 +63,6 @@ struct IndiMathParams : IndicatorParams { mode_2 = _mode_2; op_fn = _op; op_mode = MATH_OP_MODE_CUSTOM_FUNCTION; - // SetDataValueRange(IDATA_RANGE_MIXED); shift = _shift; shift_1 = _shift_1; shift_2 = _shift_2; @@ -85,7 +83,8 @@ class Indi_Math : public IndicatorTickOrCandleSource { * Class constructor. */ Indi_Math(IndiMathParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_INDICATOR), _indi_src){}; + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_INDICATOR, IDATA_RANGE_MIXED), _indi_src){}; Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SPECIAL_MATH, _tf, _shift){}; diff --git a/Strategy.mqh b/Strategy.mqh index 07179d1e2..898f6c012 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -1210,9 +1210,8 @@ class Strategy : public Object { StrategyPriceStop _psm(_method); _psm.SetChartParams(_chart.GetParams()); if (Object::IsValid(_indi)) { - int _ishift = 12; // @todo: Make it dynamic or as variable. - float _value = 0.0f; // @todo - // float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); + int _ishift = 12; // @todo: Make it dynamic or as variable. + float _value = _indi.GetValuePrice(_ishift, 0, _direction > 0 ? PRICE_HIGH : PRICE_LOW); _value = _value + (float)Math::ChangeByPct(fabs(_value - _chart.GetCloseOffer(0)), _level) * _direction; _psm.SetIndicatorPriceValue(_value); /* From 17373a567ca81d382e2fd0f5834d7d77718ff2d3 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 26 Jun 2022 19:38:06 +0100 Subject: [PATCH 79/81] Moves indicator data related methods to IndicatorData --- Indicator.mqh | 260 ---------------------------------------------- IndicatorData.mqh | 260 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 260 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index f44ce84e0..d93954818 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -169,14 +169,6 @@ class Indicator : public IndicatorData { return istate.Get(_param); } - /** - * Gets an indicator property flag. - */ - bool GetFlag(INDICATOR_ENTRY_FLAGS _prop, int _shift = 0) { - IndicatorDataEntry _entry = GetEntry(_shift >= 0 ? _shift : iparams.GetShift()); - return _entry.CheckFlag(_prop); - } - /* Setters */ /** @@ -332,258 +324,6 @@ class Indicator : public IndicatorData { */ virtual IndicatorBase* FetchDataSource(ENUM_INDICATOR_TYPE _id) { return NULL; } - /* State methods */ - - /** - * Checks for crossover. - * - * @return - * Returns true when values are crossing over, otherwise false. - */ - bool IsCrossover(int _shift1 = 0, int _shift2 = 1, int _mode1 = 0, int _mode2 = 0) { - double _curr_value1 = GetEntry(_shift1)[_mode1]; - double _prev_value1 = GetEntry(_shift2)[_mode1]; - double _curr_value2 = GetEntry(_shift1)[_mode2]; - double _prev_value2 = GetEntry(_shift2)[_mode2]; - return ((_curr_value1 > _prev_value1 && _curr_value2 < _prev_value2) || - (_prev_value1 > _curr_value1 && _prev_value2 < _curr_value2)); - } - - /** - * Checks if values are decreasing. - * - * @param int _rows - * Numbers of rows to check. - * @param int _mode - * Indicator index mode to check. - * @param int _shift - * Shift which is the final value to take into the account. - * - * @return - * Returns true when values are increasing. - */ - bool IsDecreasing(int _rows = 1, int _mode = 0, int _shift = 0) { - bool _result = true; - for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { - IndicatorDataEntry _entry_curr = GetEntry(i); - IndicatorDataEntry _entry_prev = GetEntry(i + 1); - _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] < _entry_prev[_mode]; - if (!_result) { - break; - } - } - return _result; - } - - /** - * Checks if value decreased by the given percentage value. - * - * @param int _pct - * Percentage value to use for comparison. - * @param int _mode - * Indicator index mode to use. - * @param int _shift - * Indicator value shift to use. - * @param int _count - * Count of bars to compare change backward. - * @param int _hundreds - * When true, use percentage in hundreds, otherwise 1 is 100%. - * - * @return - * Returns true when value increased. - */ - bool IsDecByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { - bool _result = true; - IndicatorDataEntry _v0 = GetEntry(_shift); - IndicatorDataEntry _v1 = GetEntry(_shift + _count); - _result &= _v0.IsValid() && _v1.IsValid(); - _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) < _pct; - return _result; - } - - /** - * Checks if values are increasing. - * - * @param int _rows - * Numbers of rows to check. - * @param int _mode - * Indicator index mode to check. - * @param int _shift - * Shift which is the final value to take into the account. - * - * @return - * Returns true when values are increasing. - */ - bool IsIncreasing(int _rows = 1, int _mode = 0, int _shift = 0) { - bool _result = true; - for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { - IndicatorDataEntry _entry_curr = GetEntry(i); - IndicatorDataEntry _entry_prev = GetEntry(i + 1); - _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] > _entry_prev[_mode]; - if (!_result) { - break; - } - } - return _result; - } - - /** - * Checks if value increased by the given percentage value. - * - * @param int _pct - * Percentage value to use for comparison. - * @param int _mode - * Indicator index mode to use. - * @param int _shift - * Indicator value shift to use. - * @param int _count - * Count of bars to compare change backward. - * @param int _hundreds - * When true, use percentage in hundreds, otherwise 1 is 100%. - * - * @return - * Returns true when value increased. - */ - bool IsIncByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { - bool _result = true; - IndicatorDataEntry _v0 = GetEntry(_shift); - IndicatorDataEntry _v1 = GetEntry(_shift + _count); - _result &= _v0.IsValid() && _v1.IsValid(); - _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) > _pct; - return _result; - } - - /* Getters */ - - /** - * Returns the highest bar's index (shift). - */ - template - int GetHighest(int count = WHOLE_ARRAY, int start_bar = 0) { - int max_idx = -1; - double max = -DBL_MAX; - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMax(GetModeCount()); - if (value > max) { - max = value; - max_idx = shift; - } - } - - return max_idx; - } - - /** - * Returns the lowest bar's index (shift). - */ - template - int GetLowest(int count = WHOLE_ARRAY, int start_bar = 0) { - int min_idx = -1; - double min = DBL_MAX; - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMin(GetModeCount()); - if (value < min) { - min = value; - min_idx = shift; - } - } - - return min_idx; - } - - /** - * Returns the highest value. - */ - template - double GetMax(int start_bar = 0, int count = WHOLE_ARRAY) { - double max = NULL; - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMax(_max_modes); - if (max == NULL || value > max) { - max = value; - } - } - - return max; - } - - /** - * Returns the lowest value. - */ - template - double GetMin(int start_bar, int count = WHOLE_ARRAY) { - double min = NULL; - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - double value = GetEntry(shift).GetMin(_max_modes); - if (min == NULL || value < min) { - min = value; - } - } - - return min; - } - - /** - * Returns average value. - */ - template - double GetAvg(int start_bar, int count = WHOLE_ARRAY) { - int num_values = 0; - double sum = 0; - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - double value_min = GetEntry(shift).GetMin(_max_modes); - double value_max = GetEntry(shift).GetMax(_max_modes); - - sum += value_min + value_max; - num_values += 2; - } - - return sum / num_values; - } - - /** - * Returns median of values. - */ - template - double GetMed(int start_bar, int count = WHOLE_ARRAY) { - double array[]; - - int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); - int num_bars = last_bar - start_bar + 1; - int index = 0; - int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); - - ArrayResize(array, num_bars); - - for (int shift = start_bar; shift <= last_bar; ++shift) { - array[index++] = GetEntry(shift).GetAvg(_max_modes); - } - - ArraySort(array); - double median; - int len = ArraySize(array); - if (len % 2 == 0) { - median = (array[len / 2] + array[(len / 2) - 1]) / 2; - } else { - median = array[len / 2]; - } - - return median; - } - /** * Returns currently selected data source doing validation. */ diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 24e87b092..1806f44f6 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -138,6 +138,14 @@ class IndicatorData : public IndicatorBase { return istate.Get(_prop); } + /** + * Gets an indicator property flag. + */ + bool GetFlag(INDICATOR_ENTRY_FLAGS _prop, int _shift = 0) { + IndicatorDataEntry _entry = GetEntry(_shift); + return _entry.CheckFlag(_prop); + } + /** * Returns price corresponding to indicator value for a given shift and mode. * @@ -168,6 +176,258 @@ class IndicatorData : public IndicatorBase { return _price; } + /* State methods */ + + /** + * Checks for crossover. + * + * @return + * Returns true when values are crossing over, otherwise false. + */ + bool IsCrossover(int _shift1 = 0, int _shift2 = 1, int _mode1 = 0, int _mode2 = 0) { + double _curr_value1 = GetEntry(_shift1)[_mode1]; + double _prev_value1 = GetEntry(_shift2)[_mode1]; + double _curr_value2 = GetEntry(_shift1)[_mode2]; + double _prev_value2 = GetEntry(_shift2)[_mode2]; + return ((_curr_value1 > _prev_value1 && _curr_value2 < _prev_value2) || + (_prev_value1 > _curr_value1 && _prev_value2 < _curr_value2)); + } + + /** + * Checks if values are decreasing. + * + * @param int _rows + * Numbers of rows to check. + * @param int _mode + * Indicator index mode to check. + * @param int _shift + * Shift which is the final value to take into the account. + * + * @return + * Returns true when values are increasing. + */ + bool IsDecreasing(int _rows = 1, int _mode = 0, int _shift = 0) { + bool _result = true; + for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { + IndicatorDataEntry _entry_curr = GetEntry(i); + IndicatorDataEntry _entry_prev = GetEntry(i + 1); + _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] < _entry_prev[_mode]; + if (!_result) { + break; + } + } + return _result; + } + + /** + * Checks if value decreased by the given percentage value. + * + * @param int _pct + * Percentage value to use for comparison. + * @param int _mode + * Indicator index mode to use. + * @param int _shift + * Indicator value shift to use. + * @param int _count + * Count of bars to compare change backward. + * @param int _hundreds + * When true, use percentage in hundreds, otherwise 1 is 100%. + * + * @return + * Returns true when value increased. + */ + bool IsDecByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { + bool _result = true; + IndicatorDataEntry _v0 = GetEntry(_shift); + IndicatorDataEntry _v1 = GetEntry(_shift + _count); + _result &= _v0.IsValid() && _v1.IsValid(); + _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) < _pct; + return _result; + } + + /** + * Checks if values are increasing. + * + * @param int _rows + * Numbers of rows to check. + * @param int _mode + * Indicator index mode to check. + * @param int _shift + * Shift which is the final value to take into the account. + * + * @return + * Returns true when values are increasing. + */ + bool IsIncreasing(int _rows = 1, int _mode = 0, int _shift = 0) { + bool _result = true; + for (int i = _shift + _rows - 1; i >= _shift && _result; i--) { + IndicatorDataEntry _entry_curr = GetEntry(i); + IndicatorDataEntry _entry_prev = GetEntry(i + 1); + _result &= _entry_curr.IsValid() && _entry_prev.IsValid() && _entry_curr[_mode] > _entry_prev[_mode]; + if (!_result) { + break; + } + } + return _result; + } + + /** + * Checks if value increased by the given percentage value. + * + * @param int _pct + * Percentage value to use for comparison. + * @param int _mode + * Indicator index mode to use. + * @param int _shift + * Indicator value shift to use. + * @param int _count + * Count of bars to compare change backward. + * @param int _hundreds + * When true, use percentage in hundreds, otherwise 1 is 100%. + * + * @return + * Returns true when value increased. + */ + bool IsIncByPct(float _pct, int _mode = 0, int _shift = 0, int _count = 1, bool _hundreds = true) { + bool _result = true; + IndicatorDataEntry _v0 = GetEntry(_shift); + IndicatorDataEntry _v1 = GetEntry(_shift + _count); + _result &= _v0.IsValid() && _v1.IsValid(); + _result &= _result && Math::ChangeInPct(_v1[_mode], _v0[_mode], _hundreds) > _pct; + return _result; + } + + /* Getters */ + + /** + * Returns the highest bar's index (shift). + */ + template + int GetHighest(int count = WHOLE_ARRAY, int start_bar = 0) { + int max_idx = -1; + double max = -DBL_MAX; + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + double value = GetEntry(shift).GetMax(GetModeCount()); + if (value > max) { + max = value; + max_idx = shift; + } + } + + return max_idx; + } + + /** + * Returns the lowest bar's index (shift). + */ + template + int GetLowest(int count = WHOLE_ARRAY, int start_bar = 0) { + int min_idx = -1; + double min = DBL_MAX; + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + double value = GetEntry(shift).GetMin(GetModeCount()); + if (value < min) { + min = value; + min_idx = shift; + } + } + + return min_idx; + } + + /** + * Returns the highest value. + */ + template + double GetMax(int start_bar = 0, int count = WHOLE_ARRAY) { + double max = NULL; + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + double value = GetEntry(shift).GetMax(_max_modes); + if (max == NULL || value > max) { + max = value; + } + } + + return max; + } + + /** + * Returns the lowest value. + */ + template + double GetMin(int start_bar, int count = WHOLE_ARRAY) { + double min = NULL; + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + double value = GetEntry(shift).GetMin(_max_modes); + if (min == NULL || value < min) { + min = value; + } + } + + return min; + } + + /** + * Returns average value. + */ + template + double GetAvg(int start_bar, int count = WHOLE_ARRAY) { + int num_values = 0; + double sum = 0; + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + double value_min = GetEntry(shift).GetMin(_max_modes); + double value_max = GetEntry(shift).GetMax(_max_modes); + + sum += value_min + value_max; + num_values += 2; + } + + return sum / num_values; + } + + /** + * Returns median of values. + */ + template + double GetMed(int start_bar, int count = WHOLE_ARRAY) { + double array[]; + + int last_bar = count == WHOLE_ARRAY ? (int)(GetBarShift(GetLastBarTime())) : (start_bar + count - 1); + int num_bars = last_bar - start_bar + 1; + int index = 0; + int _max_modes = Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)); + + ArrayResize(array, num_bars); + + for (int shift = start_bar; shift <= last_bar; ++shift) { + array[index++] = GetEntry(shift).GetAvg(_max_modes); + } + + ArraySort(array); + double median; + int len = ArraySize(array); + if (len % 2 == 0) { + median = (array[len / 2] + array[(len / 2) - 1]) / 2; + } else { + median = array[len / 2]; + } + + return median; + } + /* Data methods */ /** From b010f5dbb7d4a3163716064f536f2da1de46fecb Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 26 Jun 2022 17:48:23 +0100 Subject: [PATCH 80/81] Indicators: Adds Indicator source type and mode to constructor's argument. Other minor indicator code fixes. Fixes indicator tests. --- Indicator.mqh | 2 +- IndicatorData.mqh | 6 +-- Indicators/Bitwise/Indi_Candle.mqh | 5 ++- Indicators/Bitwise/Indi_Pattern.mqh | 6 ++- Indicators/Indi_AC.mqh | 6 ++- Indicators/Indi_AD.mqh | 9 +++-- Indicators/Indi_ADX.mqh | 11 +++--- Indicators/Indi_ADXW.mqh | 8 +++- Indicators/Indi_AMA.mqh | 9 +++-- Indicators/Indi_AO.mqh | 6 ++- Indicators/Indi_ASI.mqh | 6 ++- Indicators/Indi_ATR.mqh | 6 ++- Indicators/Indi_Alligator.mqh | 8 ++-- Indicators/Indi_AppliedPrice.mqh | 6 ++- Indicators/Indi_BWMFI.mqh | 11 +++--- Indicators/Indi_BWZT.mqh | 11 +++--- Indicators/Indi_Bands.mqh | 9 +++-- Indicators/Indi_BearsPower.mqh | 6 ++- Indicators/Indi_BullsPower.mqh | 6 ++- Indicators/Indi_CCI.mqh | 8 ++-- Indicators/Indi_CHO.mqh | 6 ++- Indicators/Indi_CHV.mqh | 6 ++- Indicators/Indi_ColorBars.mqh | 6 ++- Indicators/Indi_ColorCandlesDaily.mqh | 6 ++- Indicators/Indi_ColorLine.mqh | 6 ++- Indicators/Indi_CustomMovingAverage.mqh | 6 ++- Indicators/Indi_DEMA.mqh | 6 ++- Indicators/Indi_DeMarker.mqh | 6 ++- Indicators/Indi_Demo.mqh | 6 ++- Indicators/Indi_DetrendedPrice.mqh | 6 ++- Indicators/Indi_Drawer.mqh | 8 +++- Indicators/Indi_Envelopes.mqh | 6 ++- Indicators/Indi_Force.mqh | 6 ++- Indicators/Indi_FractalAdaptiveMA.mqh | 6 ++- Indicators/Indi_Fractals.mqh | 7 ++-- Indicators/Indi_Gator.mqh | 5 ++- Indicators/Indi_HeikenAshi.mqh | 10 +++-- Indicators/Indi_Ichimoku.mqh | 7 +++- Indicators/Indi_Killzones.mqh | 5 ++- Indicators/Indi_MA.mqh | 8 ++-- Indicators/Indi_MACD.mqh | 11 +++--- Indicators/Indi_MFI.mqh | 6 ++- Indicators/Indi_MassIndex.mqh | 6 ++- Indicators/Indi_Momentum.mqh | 6 ++- Indicators/Indi_OBV.mqh | 6 ++- Indicators/Indi_OsMA.mqh | 6 ++- Indicators/Indi_Pivot.mqh | 6 ++- Indicators/Indi_PriceChannel.mqh | 6 ++- Indicators/Indi_PriceFeeder.mqh | 7 +++- Indicators/Indi_PriceVolumeTrend.mqh | 6 ++- Indicators/Indi_RS.mqh | 6 ++- Indicators/Indi_RSI.mqh | 6 ++- Indicators/Indi_RVI.mqh | 11 +++--- Indicators/Indi_RateOfChange.mqh | 6 ++- Indicators/Indi_SAR.mqh | 6 ++- Indicators/Indi_StdDev.mqh | 8 ++-- Indicators/Indi_Stochastic.mqh | 11 +++--- Indicators/Indi_TEMA.mqh | 6 ++- Indicators/Indi_TRIX.mqh | 6 ++- Indicators/Indi_UltimateOscillator.mqh | 6 ++- Indicators/Indi_VIDYA.mqh | 6 ++- Indicators/Indi_VROC.mqh | 6 ++- Indicators/Indi_Volumes.mqh | 6 ++- Indicators/Indi_WPR.mqh | 6 ++- Indicators/Indi_WilliamsAD.mqh | 6 ++- Indicators/Indi_ZigZag.mqh | 7 ++-- Indicators/Indi_ZigZagColor.mqh | 5 ++- Indicators/OHLC/Indi_OHLC.mqh | 7 +++- Indicators/Price/Indi_Price.mqh | 7 +++- Indicators/Special/Indi_Custom.mqh | 14 ++++--- Indicators/Special/Indi_Math.mqh | 6 ++- Indicators/Tick/Indi_TickMt.mqh | 6 ++- tests/DrawIndicatorTest.mq5 | 24 ++++++------ tests/IndicatorsTest.mq5 | 51 ++++++++++--------------- 74 files changed, 347 insertions(+), 221 deletions(-) diff --git a/Indicator.mqh b/Indicator.mqh index d93954818..461bcc8f2 100644 --- a/Indicator.mqh +++ b/Indicator.mqh @@ -130,7 +130,7 @@ class Indicator : public IndicatorData { * Class constructor. */ Indicator(const TS& _iparams, const IndicatorDataParams& _idparams, IndicatorData* _indi_src = NULL, int _indi_mode = 0) - : IndicatorData(_idparams) { + : IndicatorData(_idparams, _indi_src, _indi_mode) { iparams = _iparams; Init(); } diff --git a/IndicatorData.mqh b/IndicatorData.mqh index 1806f44f6..21e374cee 100644 --- a/IndicatorData.mqh +++ b/IndicatorData.mqh @@ -747,15 +747,15 @@ class IndicatorData : public IndicatorBase { " must select source indicator's mode via SetDataSourceMode(int). Defaulting to mode 0."); _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); DebugBreak(); - } else if (_source.GetModeCount() == 1 && + } else if (_source.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == 1 && _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) == -1) { _target.idparams.Set(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE), 0); } else if (_target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) < 0 || _target.idparams.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_DATA_SRC_MODE)) > - _source.GetModeCount()) { + _source.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES))) { Alert("Error! ", _target.GetName(), " must select valid source indicator's mode via SetDataSourceMode(int) between 0 and ", - _source.GetModeCount(), "."); + _source.Get(STRUCT_ENUM(IndicatorDataParams, IDATA_PARAM_MAX_MODES)), "."); DebugBreak(); } } diff --git a/Indicators/Bitwise/Indi_Candle.mqh b/Indicators/Bitwise/Indi_Candle.mqh index 053710dff..7e4a4f5d3 100644 --- a/Indicators/Bitwise/Indi_Candle.mqh +++ b/Indicators/Bitwise/Indi_Candle.mqh @@ -50,9 +50,10 @@ class Indi_Candle : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Candle(CandleParams &_p, IndicatorData *_indi_src = NULL) + Indi_Candle(CandleParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_INT, IDATA_BUILTIN, IDATA_RANGE_RANGE), + _p, IndicatorDataParams::GetInstance(1, TYPE_INT, _idstype, IDATA_RANGE_RANGE, _indi_src_mode), _indi_src){}; Indi_Candle(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CANDLE, _tf, _shift){}; diff --git a/Indicators/Bitwise/Indi_Pattern.mqh b/Indicators/Bitwise/Indi_Pattern.mqh index 38641ff40..cc223770c 100644 --- a/Indicators/Bitwise/Indi_Pattern.mqh +++ b/Indicators/Bitwise/Indi_Pattern.mqh @@ -47,9 +47,11 @@ class Indi_Pattern : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Pattern(IndiPatternParams& _p, IndicatorData* _indi_src = NULL) + Indi_Pattern(IndiPatternParams& _p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData* _indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(5, TYPE_UINT, IDATA_BUILTIN, IDATA_RANGE_BITWISE), _indi_src){}; + _p, IndicatorDataParams::GetInstance(5, TYPE_UINT, _idstype, IDATA_RANGE_BITWISE, _indi_src_mode), + _indi_src){}; Indi_Pattern(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PATTERN, _tf, _shift){}; diff --git a/Indicators/Indi_AC.mqh b/Indicators/Indi_AC.mqh index 78564827f..2d9e905f8 100644 --- a/Indicators/Indi_AC.mqh +++ b/Indicators/Indi_AC.mqh @@ -67,9 +67,11 @@ class Indi_AC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AC(IndiACParams &_p, IndicatorData *_indi_src = NULL) + Indi_AC(IndiACParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); }; Indi_AC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AC, _tf, _shift) { diff --git a/Indicators/Indi_AD.mqh b/Indicators/Indi_AD.mqh index e7e8b1a49..279f380c4 100644 --- a/Indicators/Indi_AD.mqh +++ b/Indicators/Indi_AD.mqh @@ -52,9 +52,12 @@ class Indi_AD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AD(IndiADParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + Indi_AD(IndiADParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_AD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AD, _tf, _shift) { iparams.SetTf(_tf); }; diff --git a/Indicators/Indi_ADX.mqh b/Indicators/Indi_ADX.mqh index 799763c03..527749bc7 100644 --- a/Indicators/Indi_ADX.mqh +++ b/Indicators/Indi_ADX.mqh @@ -65,11 +65,12 @@ class Indi_ADX : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ADX(IndiADXParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), - _indi_src) { + Indi_ADX(IndiADXParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) { Init(); } Indi_ADX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift) { diff --git a/Indicators/Indi_ADXW.mqh b/Indicators/Indi_ADXW.mqh index 1f6b41ff8..74f1c1f89 100644 --- a/Indicators/Indi_ADXW.mqh +++ b/Indicators/Indi_ADXW.mqh @@ -58,8 +58,12 @@ class Indi_ADXW : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ADXW(IndiADXWParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN), _indi_src){}; + Indi_ADXW(IndiADXWParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_ADX_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src){}; Indi_ADXW(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADXW, _tf, _shift){}; diff --git a/Indicators/Indi_AMA.mqh b/Indicators/Indi_AMA.mqh index 51f97d750..2cb1ae243 100644 --- a/Indicators/Indi_AMA.mqh +++ b/Indicators/Indi_AMA.mqh @@ -63,10 +63,11 @@ class Indi_AMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AMA(IndiAMAParams &_p, IndicatorData *_indi_src = NULL, int _indi_mode = 0) - : IndicatorTickOrCandleSource(_p, - IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), - _indi_src, _indi_mode) { + Indi_AMA(IndiAMAParams &_p, int _indi_mode = 0, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src, _indi_mode) { iparams.SetIndicatorType(INDI_AMA); }; Indi_AMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AMA, _tf, _shift){}; diff --git a/Indicators/Indi_AO.mqh b/Indicators/Indi_AO.mqh index 0cc6b9df5..783e48562 100644 --- a/Indicators/Indi_AO.mqh +++ b/Indicators/Indi_AO.mqh @@ -66,9 +66,11 @@ class Indi_AO : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_AO(IndiAOParams &_p, IndicatorData *_indi_src = NULL) + Indi_AO(IndiAOParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); }; Indi_AO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_AO, _tf, _shift) { diff --git a/Indicators/Indi_ASI.mqh b/Indicators/Indi_ASI.mqh index 0e0f8ee31..d520cfb5d 100644 --- a/Indicators/Indi_ASI.mqh +++ b/Indicators/Indi_ASI.mqh @@ -61,9 +61,11 @@ class Indi_ASI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ASI(IndiASIParams &_p, IndicatorData *_indi_src = NULL) + Indi_ASI(IndiASIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_ONCALCULATE, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ONCALCULATE, IDATA_RANGE_MIXED), _indi_src) { + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); }; Indi_ASI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ASI, _tf, _shift) { diff --git a/Indicators/Indi_ATR.mqh b/Indicators/Indi_ATR.mqh index 76fb9014e..37641e945 100644 --- a/Indicators/Indi_ATR.mqh +++ b/Indicators/Indi_ATR.mqh @@ -55,9 +55,11 @@ class Indi_ATR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ATR(IndiATRParams &_p, IndicatorData *_indi_src = NULL) + Indi_ATR(IndiATRParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_ATR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ATR, _tf, _shift){}; /** diff --git a/Indicators/Indi_Alligator.mqh b/Indicators/Indi_Alligator.mqh index 74693c57b..c2f1b7532 100644 --- a/Indicators/Indi_Alligator.mqh +++ b/Indicators/Indi_Alligator.mqh @@ -99,11 +99,11 @@ class Indi_Alligator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Alligator(IndiAlligatorParams &_p, IndicatorData *_indi_src = NULL) + Indi_Alligator(IndiAlligatorParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), - _indi_src) {} + _p, IndicatorDataParams::GetInstance(FINAL_ALLIGATOR_LINE_ENTRY, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE), + _indi_src, _indi_src_mode) {} Indi_Alligator(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ADX, _tf, _shift){}; diff --git a/Indicators/Indi_AppliedPrice.mqh b/Indicators/Indi_AppliedPrice.mqh index 638d4500c..82a8399a9 100644 --- a/Indicators/Indi_AppliedPrice.mqh +++ b/Indicators/Indi_AppliedPrice.mqh @@ -55,9 +55,11 @@ class Indi_AppliedPrice : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_BWMFI(IndiBWIndiMFIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_BWMFI_BUFFER_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), - _indi_src) { + Indi_BWMFI(IndiBWIndiMFIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_BWMFI_BUFFER_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); } Indi_BWMFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_BWZT.mqh b/Indicators/Indi_BWZT.mqh index 53b5b9729..34a3f0df9 100644 --- a/Indicators/Indi_BWZT.mqh +++ b/Indicators/Indi_BWZT.mqh @@ -74,11 +74,12 @@ class Indi_BWZT : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_BWZT(IndiBWZTParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_INDI_BWZT_MODE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), - _indi_src) { + Indi_BWZT(IndiBWZTParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_BWZT_MODE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); }; Indi_BWZT(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_Bands.mqh b/Indicators/Indi_Bands.mqh index 6f6526f96..440158315 100644 --- a/Indicators/Indi_Bands.mqh +++ b/Indicators/Indi_Bands.mqh @@ -94,9 +94,12 @@ class Indi_Bands : public IndicatorTickSource { /** * Class constructor. */ - Indi_Bands(IndiBandsParams &_p, IndicatorData *_indi_src = NULL, int _mode = 0) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src, - _mode) { + Indi_Bands(IndiBandsParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickSource(_p, + IndicatorDataParams::GetInstance(FINAL_BANDS_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) { Init(); } Indi_Bands(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_BANDS, _tf, _shift) { diff --git a/Indicators/Indi_BearsPower.mqh b/Indicators/Indi_BearsPower.mqh index de0318428..edaa5cdd6 100644 --- a/Indicators/Indi_BearsPower.mqh +++ b/Indicators/Indi_BearsPower.mqh @@ -55,9 +55,11 @@ class Indi_BearsPower : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_BearsPower(IndiBearsPowerParams &_p, IndicatorData *_indi_src = NULL) + Indi_BearsPower(IndiBearsPowerParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_BearsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BEARS, _tf, _shift) {} diff --git a/Indicators/Indi_BullsPower.mqh b/Indicators/Indi_BullsPower.mqh index 14a8884ed..dfbc27119 100644 --- a/Indicators/Indi_BullsPower.mqh +++ b/Indicators/Indi_BullsPower.mqh @@ -55,9 +55,11 @@ class Indi_BullsPower : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_BullsPower(IndiBullsPowerParams &_p, IndicatorData *_indi_src = NULL) + Indi_BullsPower(IndiBullsPowerParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_BullsPower(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_BULLS, _tf, _shift) {} diff --git a/Indicators/Indi_CCI.mqh b/Indicators/Indi_CCI.mqh index cf7f2bfcd..57775a615 100644 --- a/Indicators/Indi_CCI.mqh +++ b/Indicators/Indi_CCI.mqh @@ -62,9 +62,11 @@ class Indi_CCI : public IndicatorTickSource { /** * Class constructor. */ - Indi_CCI(IndiCCIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), - _indi_src) {} + Indi_CCI(IndiCCIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_CCI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_CCI, _tf, _shift) {} /** diff --git a/Indicators/Indi_CHO.mqh b/Indicators/Indi_CHO.mqh index f5f48157e..1e05734b0 100644 --- a/Indicators/Indi_CHO.mqh +++ b/Indicators/Indi_CHO.mqh @@ -58,9 +58,11 @@ class Indi_CHO : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHO(IndiCHOParams &_p, IndicatorData *_indi_src = NULL) + Indi_CHO(IndiCHOParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_CHO(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN, _tf, _shift){}; diff --git a/Indicators/Indi_CHV.mqh b/Indicators/Indi_CHV.mqh index 7b8119289..9d514d3f7 100644 --- a/Indicators/Indi_CHV.mqh +++ b/Indicators/Indi_CHV.mqh @@ -59,9 +59,11 @@ class Indi_CHV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_CHV(IndiCHVParams &_p, IndicatorData *_indi_src = NULL) + Indi_CHV(IndiCHVParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_CHV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_CHAIKIN_V, _tf, _shift){}; diff --git a/Indicators/Indi_ColorBars.mqh b/Indicators/Indi_ColorBars.mqh index 78082f8a5..cb920a588 100644 --- a/Indicators/Indi_ColorBars.mqh +++ b/Indicators/Indi_ColorBars.mqh @@ -46,9 +46,11 @@ class Indi_ColorBars : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ColorBars(IndiColorBarsParams &_p, IndicatorData *_indi_src = NULL) + Indi_ColorBars(IndiColorBarsParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(5, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(5, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_ColorBars(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_BARS, _tf, _shift){}; diff --git a/Indicators/Indi_ColorCandlesDaily.mqh b/Indicators/Indi_ColorCandlesDaily.mqh index e47528dac..e848eb6f0 100644 --- a/Indicators/Indi_ColorCandlesDaily.mqh +++ b/Indicators/Indi_ColorCandlesDaily.mqh @@ -46,9 +46,11 @@ class Indi_ColorCandlesDaily : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ColorLine(IndiColorLineParams &_p, IndicatorData *_indi_src = NULL) + Indi_ColorLine(IndiColorLineParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_ColorLine(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_COLOR_LINE, _tf, _shift){}; diff --git a/Indicators/Indi_CustomMovingAverage.mqh b/Indicators/Indi_CustomMovingAverage.mqh index 8db902680..8e4b16e43 100644 --- a/Indicators/Indi_CustomMovingAverage.mqh +++ b/Indicators/Indi_CustomMovingAverage.mqh @@ -59,9 +59,11 @@ class Indi_CustomMovingAverage : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DEMA(IndiDEIndiMAParams &_p, IndicatorData *_indi_src = NULL) + Indi_DEMA(IndiDEIndiMAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) {} Indi_DEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMA, _tf, _shift) {} diff --git a/Indicators/Indi_DeMarker.mqh b/Indicators/Indi_DeMarker.mqh index e45f2420b..d20b21dab 100644 --- a/Indicators/Indi_DeMarker.mqh +++ b/Indicators/Indi_DeMarker.mqh @@ -53,9 +53,11 @@ class Indi_DeMarker : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_DeMarker(IndiDeMarkerParams &_p, IndicatorData *_indi_src = NULL) + Indi_DeMarker(IndiDeMarkerParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_DeMarker(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMARKER, _tf, _shift) {} diff --git a/Indicators/Indi_Demo.mqh b/Indicators/Indi_Demo.mqh index 3a561463a..7adc7080e 100644 --- a/Indicators/Indi_Demo.mqh +++ b/Indicators/Indi_Demo.mqh @@ -53,9 +53,11 @@ class Indi_Demo : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Demo(IndiDemoParams &_p, IndicatorData *_indi_src = NULL) + Indi_Demo(IndiDemoParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_Demo(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_DEMO, _tf, _shift){}; diff --git a/Indicators/Indi_DetrendedPrice.mqh b/Indicators/Indi_DetrendedPrice.mqh index 9767ffe23..ab3195936 100644 --- a/Indicators/Indi_DetrendedPrice.mqh +++ b/Indicators/Indi_DetrendedPrice.mqh @@ -52,9 +52,11 @@ class Indi_DetrendedPrice : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Drawer(const IndiDrawerParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(0, TYPE_DOUBLE), _indi_src), redis(true) { + Indi_Drawer(const IndiDrawerParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(0, TYPE_DOUBLE, _idstype, IDATA_RANGE_UNKNOWN, _indi_src_mode), + _indi_src), + redis(true) { Init(); } Indi_Drawer(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_Envelopes.mqh b/Indicators/Indi_Envelopes.mqh index 8fc30e78e..431598d19 100644 --- a/Indicators/Indi_Envelopes.mqh +++ b/Indicators/Indi_Envelopes.mqh @@ -91,9 +91,11 @@ class Indi_Envelopes : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Envelopes(IndiEnvelopesParams &_p, IndicatorData *_indi_src = NULL) + Indi_Envelopes(IndiEnvelopesParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) { + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) { Init(); } Indi_Envelopes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_Force.mqh b/Indicators/Indi_Force.mqh index 83476a19b..0880d6ee3 100644 --- a/Indicators/Indi_Force.mqh +++ b/Indicators/Indi_Force.mqh @@ -70,9 +70,11 @@ class Indi_Force : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Force(IndiForceParams &_p, IndicatorData *_indi_src = NULL) + Indi_Force(IndiForceParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_Force(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FORCE, _tf, _shift) {} diff --git a/Indicators/Indi_FractalAdaptiveMA.mqh b/Indicators/Indi_FractalAdaptiveMA.mqh index cf0751685..33a72fb83 100644 --- a/Indicators/Indi_FractalAdaptiveMA.mqh +++ b/Indicators/Indi_FractalAdaptiveMA.mqh @@ -54,9 +54,11 @@ class Indi_FrAMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_FrAMA(IndiFrAIndiMAParams &_p, IndicatorData *_indi_src = NULL) + Indi_FrAMA(IndiFrAIndiMAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_FrAMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_FRAMA, _tf, _shift){}; diff --git a/Indicators/Indi_Fractals.mqh b/Indicators/Indi_Fractals.mqh index 2c074b427..fecd71daf 100644 --- a/Indicators/Indi_Fractals.mqh +++ b/Indicators/Indi_Fractals.mqh @@ -60,10 +60,11 @@ class Indi_Fractals : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Fractals(IndiFractalsParams &_p, IndicatorData *_indi_src = NULL) + Indi_Fractals(IndiFractalsParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource(_p, - IndicatorDataParams::GetInstance(FINAL_LO_UP_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, - IDATA_RANGE_PRICE_ON_SIGNAL), + IndicatorDataParams::GetInstance(FINAL_LO_UP_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE_ON_SIGNAL, _indi_src_mode), _indi_src) { Init(); } diff --git a/Indicators/Indi_Gator.mqh b/Indicators/Indi_Gator.mqh index f2f094df3..dd0b06b7a 100644 --- a/Indicators/Indi_Gator.mqh +++ b/Indicators/Indi_Gator.mqh @@ -115,10 +115,11 @@ class Indi_Gator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Gator(IndiGatorParams &_p, IndicatorData *_indi_src = NULL) + Indi_Gator(IndiGatorParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_GATOR_LINE_HISTOGRAM_ENTRY, TYPE_DOUBLE, - IDATA_BUILTIN, IDATA_RANGE_MIXED), + _idstype, IDATA_RANGE_MIXED, _indi_src_mode), _indi_src) { Init(); } diff --git a/Indicators/Indi_HeikenAshi.mqh b/Indicators/Indi_HeikenAshi.mqh index 01b823e38..637efb682 100644 --- a/Indicators/Indi_HeikenAshi.mqh +++ b/Indicators/Indi_HeikenAshi.mqh @@ -82,10 +82,12 @@ class Indi_HeikenAshi : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_HeikenAshi(IndiHeikenAshiParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(FINAL_HA_MODE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), - _indi_src) { + Indi_HeikenAshi(IndiHeikenAshiParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_HA_MODE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) { Init(); } Indi_HeikenAshi(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_Ichimoku.mqh b/Indicators/Indi_Ichimoku.mqh index 2e2683ced..16ceaab94 100644 --- a/Indicators/Indi_Ichimoku.mqh +++ b/Indicators/Indi_Ichimoku.mqh @@ -95,8 +95,11 @@ class Indi_Ichimoku : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Ichimoku(IndiIchimokuParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), + Indi_Ichimoku(IndiIchimokuParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_ICHIMOKU_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE, _indi_src_mode), _indi_src) { Init(); } diff --git a/Indicators/Indi_Killzones.mqh b/Indicators/Indi_Killzones.mqh index d8a8aada2..68cbbfb28 100644 --- a/Indicators/Indi_Killzones.mqh +++ b/Indicators/Indi_Killzones.mqh @@ -96,10 +96,11 @@ class Indi_Killzones : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Killzones(IndiKillzonesParams &_p, IndicatorData *_indi_src = NULL) + Indi_Killzones(IndiKillzonesParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_CHART, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_INDI_KILLZONES_MODE_ENTRY, TYPE_FLOAT, - IDATA_CHART, IDATA_RANGE_PRICE), + _idstype, IDATA_RANGE_PRICE, _indi_src_mode), _indi_src) {} Indi_Killzones(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_KILLZONES, _tf, _shift) {} diff --git a/Indicators/Indi_MA.mqh b/Indicators/Indi_MA.mqh index 89a23e6e0..c52ef1332 100644 --- a/Indicators/Indi_MA.mqh +++ b/Indicators/Indi_MA.mqh @@ -74,9 +74,11 @@ class Indi_MA : public IndicatorTickSource { /** * Class constructor. */ - Indi_MA(IndiMAParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), - _indi_src) {} + Indi_MA(IndiMAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) {} Indi_MA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_MA, _tf, _shift) {} /** diff --git a/Indicators/Indi_MACD.mqh b/Indicators/Indi_MACD.mqh index d8c6da7f7..4d9518d64 100644 --- a/Indicators/Indi_MACD.mqh +++ b/Indicators/Indi_MACD.mqh @@ -63,11 +63,12 @@ class Indi_MACD : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MACD(IndiMACDParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), - _indi_src) {} + Indi_MACD(IndiMACDParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_MACD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MACD, _tf, _shift) {} diff --git a/Indicators/Indi_MFI.mqh b/Indicators/Indi_MFI.mqh index 238334d19..2d8b4a800 100644 --- a/Indicators/Indi_MFI.mqh +++ b/Indicators/Indi_MFI.mqh @@ -55,9 +55,11 @@ class Indi_MFI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MFI(IndiMFIParams &_p, IndicatorData *_indi_src = NULL) + Indi_MFI(IndiMFIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_MFI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MFI, _tf, _shift) {} /** diff --git a/Indicators/Indi_MassIndex.mqh b/Indicators/Indi_MassIndex.mqh index 95cf7f4e6..dbd06b000 100644 --- a/Indicators/Indi_MassIndex.mqh +++ b/Indicators/Indi_MassIndex.mqh @@ -54,9 +54,11 @@ class Indi_MassIndex : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_MassIndex(IndiMassIndexParams &_p, IndicatorData *_indi_src = NULL) + Indi_MassIndex(IndiMassIndexParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_MassIndex(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MASS_INDEX, _tf, _shift){}; diff --git a/Indicators/Indi_Momentum.mqh b/Indicators/Indi_Momentum.mqh index 0f13c5904..e228e8224 100644 --- a/Indicators/Indi_Momentum.mqh +++ b/Indicators/Indi_Momentum.mqh @@ -65,9 +65,11 @@ class Indi_Momentum : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Momentum(IndiMomentumParams &_p, IndicatorData *_indi_src = NULL) + Indi_Momentum(IndiMomentumParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_Momentum(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_MOMENTUM, _tf, _shift) {} diff --git a/Indicators/Indi_OBV.mqh b/Indicators/Indi_OBV.mqh index 38ef7d284..7410d831a 100644 --- a/Indicators/Indi_OBV.mqh +++ b/Indicators/Indi_OBV.mqh @@ -62,9 +62,11 @@ class Indi_OBV : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OBV(IndiOBVParams &_p, IndicatorData *_indi_src = NULL) + Indi_OBV(IndiOBVParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_OBV(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OBV, _tf, _shift) {} /** diff --git a/Indicators/Indi_OsMA.mqh b/Indicators/Indi_OsMA.mqh index faadb39b6..0a81f2308 100644 --- a/Indicators/Indi_OsMA.mqh +++ b/Indicators/Indi_OsMA.mqh @@ -62,9 +62,11 @@ class Indi_OsMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OsMA(IndiOsMAParams &_p, IndicatorData *_indi_src = NULL) + Indi_OsMA(IndiOsMAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_OsMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_OSMA, _tf, _shift) {} diff --git a/Indicators/Indi_Pivot.mqh b/Indicators/Indi_Pivot.mqh index 6dc65fbd9..e9f98d642 100644 --- a/Indicators/Indi_Pivot.mqh +++ b/Indicators/Indi_Pivot.mqh @@ -56,9 +56,11 @@ class Indi_Pivot : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Pivot(IndiPivotParams& _p, IndicatorData* _indi_src = NULL) + Indi_Pivot(IndiPivotParams& _p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData* _indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(9, TYPE_FLOAT, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src) { + _p, IndicatorDataParams::GetInstance(9, TYPE_FLOAT, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) { Init(); }; Indi_Pivot(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) diff --git a/Indicators/Indi_PriceChannel.mqh b/Indicators/Indi_PriceChannel.mqh index 23de9a63b..4d9729599 100644 --- a/Indicators/Indi_PriceChannel.mqh +++ b/Indicators/Indi_PriceChannel.mqh @@ -48,9 +48,11 @@ class Indi_PriceChannel : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RS(IndiRSParams &_p, IndicatorData *_indi_src = NULL) + Indi_RS(IndiRSParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_MATH, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_MATH, IDATA_RANGE_PRICE_DIFF), _indi_src) { + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE_DIFF, _indi_src_mode), + _indi_src) { Init(); }; Indi_RS(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RS, _tf, _shift) { diff --git a/Indicators/Indi_RSI.mqh b/Indicators/Indi_RSI.mqh index 1ccce509e..431d95470 100644 --- a/Indicators/Indi_RSI.mqh +++ b/Indicators/Indi_RSI.mqh @@ -94,9 +94,11 @@ class Indi_RSI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RSI(IndiRSIParams &_p, IndicatorData *_indi_src = NULL) + Indi_RSI(IndiRSIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_RSI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RSI, _tf, _shift) {} /** diff --git a/Indicators/Indi_RVI.mqh b/Indicators/Indi_RVI.mqh index c9435bbee..4b1458276 100644 --- a/Indicators/Indi_RVI.mqh +++ b/Indicators/Indi_RVI.mqh @@ -53,11 +53,12 @@ class Indi_RVI : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_RVI(const IndiRVIParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), - _indi_src) {} + Indi_RVI(const IndiRVIParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_RVI(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_RVI, _tf, _shift) {} /** diff --git a/Indicators/Indi_RateOfChange.mqh b/Indicators/Indi_RateOfChange.mqh index aa7c8dcd1..a6c37dd26 100644 --- a/Indicators/Indi_RateOfChange.mqh +++ b/Indicators/Indi_RateOfChange.mqh @@ -51,9 +51,11 @@ class Indi_RateOfChange : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_SAR(IndiSARParams &_p, IndicatorData *_indi_src = NULL) + Indi_SAR(IndiSARParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_PRICE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src) {} Indi_SAR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SAR, _tf, _shift) {} /** diff --git a/Indicators/Indi_StdDev.mqh b/Indicators/Indi_StdDev.mqh index 0c9ff8cd1..17a7f250e 100644 --- a/Indicators/Indi_StdDev.mqh +++ b/Indicators/Indi_StdDev.mqh @@ -77,9 +77,11 @@ class Indi_StdDev : public IndicatorTickSource { /** * Class constructor. */ - Indi_StdDev(IndiStdDevParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), - _indi_src) {} + Indi_StdDev(IndiStdDevParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src) {} Indi_StdDev(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickSource(INDI_STDDEV, _tf, _shift) {} /** diff --git a/Indicators/Indi_Stochastic.mqh b/Indicators/Indi_Stochastic.mqh index 1851dfe63..3a5ec7444 100644 --- a/Indicators/Indi_Stochastic.mqh +++ b/Indicators/Indi_Stochastic.mqh @@ -66,11 +66,12 @@ class Indi_Stochastic : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Stochastic(IndiStochParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource( - _p, - IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), - _indi_src) {} + Indi_Stochastic(IndiStochParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_SIGNAL_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_Stochastic(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_STOCHASTIC, _tf, _shift) {} diff --git a/Indicators/Indi_TEMA.mqh b/Indicators/Indi_TEMA.mqh index 597139639..73c71241c 100644 --- a/Indicators/Indi_TEMA.mqh +++ b/Indicators/Indi_TEMA.mqh @@ -54,9 +54,11 @@ class Indi_TEMA : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TEMA(IndiTEMAParams &_p, IndicatorData *_indi_src = NULL) + Indi_TEMA(IndiTEMAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_TEMA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TEMA, _tf, _shift){}; diff --git a/Indicators/Indi_TRIX.mqh b/Indicators/Indi_TRIX.mqh index 862d267e2..c8be21d65 100644 --- a/Indicators/Indi_TRIX.mqh +++ b/Indicators/Indi_TRIX.mqh @@ -52,9 +52,11 @@ class Indi_TRIX : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_TRIX(IndiTRIXParams &_p, IndicatorData *_indi_src = NULL) + Indi_TRIX(IndiTRIXParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_TRIX(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_TRIX, _tf, _shift){}; diff --git a/Indicators/Indi_UltimateOscillator.mqh b/Indicators/Indi_UltimateOscillator.mqh index 33b6c2576..906a79de3 100644 --- a/Indicators/Indi_UltimateOscillator.mqh +++ b/Indicators/Indi_UltimateOscillator.mqh @@ -66,9 +66,11 @@ class Indi_UltimateOscillator : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VIDYA(IndiVIDYAParams &_p, IndicatorData *_indi_src = NULL) + Indi_VIDYA(IndiVIDYAParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_VIDYA(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VIDYA, _tf, _shift){}; diff --git a/Indicators/Indi_VROC.mqh b/Indicators/Indi_VROC.mqh index 468ec8b53..98433c611 100644 --- a/Indicators/Indi_VROC.mqh +++ b/Indicators/Indi_VROC.mqh @@ -51,9 +51,11 @@ class Indi_VROC : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_VROC(IndiVROCParams &_p, IndicatorData *_indi_src = NULL) + Indi_VROC(IndiVROCParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_VROC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VROC, _tf, _shift){}; diff --git a/Indicators/Indi_Volumes.mqh b/Indicators/Indi_Volumes.mqh index 0db8a7745..46a12532c 100644 --- a/Indicators/Indi_Volumes.mqh +++ b/Indicators/Indi_Volumes.mqh @@ -48,9 +48,11 @@ class Indi_Volumes : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Volumes(IndiVolumesParams &_p, IndicatorData *_indi_src = NULL) + Indi_Volumes(IndiVolumesParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(2, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_Volumes(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_VOLUMES, _tf, _shift){}; diff --git a/Indicators/Indi_WPR.mqh b/Indicators/Indi_WPR.mqh index 1d872a618..f53c655ec 100644 --- a/Indicators/Indi_WPR.mqh +++ b/Indicators/Indi_WPR.mqh @@ -53,9 +53,11 @@ class Indi_WPR : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_WPR(IndiWPRParams &_p, IndicatorData *_indi_src = NULL) + Indi_WPR(IndiWPRParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_RANGE), _indi_src) {} + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_RANGE, _indi_src_mode), + _indi_src) {} Indi_WPR(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WPR, _tf, _shift) {} /** diff --git a/Indicators/Indi_WilliamsAD.mqh b/Indicators/Indi_WilliamsAD.mqh index 43e8cc399..5a09d153c 100644 --- a/Indicators/Indi_WilliamsAD.mqh +++ b/Indicators/Indi_WilliamsAD.mqh @@ -46,9 +46,11 @@ class Indi_WilliamsAD : public IndicatorTickOrCandleSource /** * Class constructor. */ - Indi_WilliamsAD(IndiWilliamsADParams &_p, IndicatorData *_indi_src = NULL) + Indi_WilliamsAD(IndiWilliamsADParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, + IndicatorData *_indi_src = NULL, int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_BUILTIN, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_WilliamsAD(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_WILLIAMS_AD, _tf, _shift){}; diff --git a/Indicators/Indi_ZigZag.mqh b/Indicators/Indi_ZigZag.mqh index 59f7df91e..ad6effa22 100644 --- a/Indicators/Indi_ZigZag.mqh +++ b/Indicators/Indi_ZigZag.mqh @@ -59,10 +59,11 @@ class Indi_ZigZag : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_ZigZag(IndiZigZagParams &_p, IndicatorData *_indi_src = NULL) + Indi_ZigZag(IndiZigZagParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource(_p, - IndicatorDataParams::GetInstance(FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE, - IDATA_BUILTIN, IDATA_RANGE_PRICE_ON_SIGNAL), + IndicatorDataParams::GetInstance(FINAL_ZIGZAG_LINE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE_ON_SIGNAL), _indi_src) {} Indi_ZigZag(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_ZIGZAG, _tf, _shift) {} diff --git a/Indicators/Indi_ZigZagColor.mqh b/Indicators/Indi_ZigZagColor.mqh index cad1f31db..4dd0303a4 100644 --- a/Indicators/Indi_ZigZagColor.mqh +++ b/Indicators/Indi_ZigZagColor.mqh @@ -56,9 +56,10 @@ class Indi_ZigZagColor : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_OHLC(IndiOHLCParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(FINAL_INDI_OHLC_MODE_ENTRY, TYPE_DOUBLE), + Indi_OHLC(IndiOHLCParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource(_p, + IndicatorDataParams::GetInstance(FINAL_INDI_OHLC_MODE_ENTRY, TYPE_DOUBLE, _idstype, + IDATA_RANGE_PRICE, _indi_src_mode), _indi_src){}; Indi_OHLC(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Price/Indi_Price.mqh b/Indicators/Price/Indi_Price.mqh index 827381fb6..e8a97a0c6 100644 --- a/Indicators/Price/Indi_Price.mqh +++ b/Indicators/Price/Indi_Price.mqh @@ -50,8 +50,11 @@ class Indi_Price : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Price(PriceIndiParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTickOrCandleSource(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE), _indi_src){}; + Indi_Price(PriceIndiParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_PRICE, _indi_src_mode), + _indi_src){}; Indi_Price(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_PRICE, _tf, _shift){}; diff --git a/Indicators/Special/Indi_Custom.mqh b/Indicators/Special/Indi_Custom.mqh index cfd0101e9..c23a3c19f 100644 --- a/Indicators/Special/Indi_Custom.mqh +++ b/Indicators/Special/Indi_Custom.mqh @@ -33,7 +33,7 @@ #endif // Includes. -#include "../../Indicator.mqh" +#include "../../Indicator/IndicatorTickOrCandleSource.h" // Structs. @@ -73,14 +73,18 @@ struct IndiCustomParams : public IndicatorParams { /** * Implements indicator class. */ -class Indi_Custom : public Indicator { +class Indi_Custom : public IndicatorTickOrCandleSource { public: /** * Class constructor. */ - Indi_Custom(IndiCustomParams &_p, IndicatorData *_indi_src = NULL) - : Indicator(_p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_ICUSTOM), _indi_src) {} - Indi_Custom(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(INDI_CUSTOM, _tf){}; + Indi_Custom(IndiCustomParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_ICUSTOM, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTickOrCandleSource( + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_UNKNOWN, _indi_src_mode), + _indi_src) {} + Indi_Custom(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) + : IndicatorTickOrCandleSource(INDI_CUSTOM, _tf, _shift){}; /** * Returns the indicator's value. diff --git a/Indicators/Special/Indi_Math.mqh b/Indicators/Special/Indi_Math.mqh index 4ed2aad41..dcf43f01b 100644 --- a/Indicators/Special/Indi_Math.mqh +++ b/Indicators/Special/Indi_Math.mqh @@ -82,9 +82,11 @@ class Indi_Math : public IndicatorTickOrCandleSource { /** * Class constructor. */ - Indi_Math(IndiMathParams &_p, IndicatorData *_indi_src = NULL) + Indi_Math(IndiMathParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_INDICATOR, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) : IndicatorTickOrCandleSource( - _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, IDATA_INDICATOR, IDATA_RANGE_MIXED), _indi_src){}; + _p, IndicatorDataParams::GetInstance(1, TYPE_DOUBLE, _idstype, IDATA_RANGE_MIXED, _indi_src_mode), + _indi_src){}; Indi_Math(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0) : IndicatorTickOrCandleSource(INDI_SPECIAL_MATH, _tf, _shift){}; diff --git a/Indicators/Tick/Indi_TickMt.mqh b/Indicators/Tick/Indi_TickMt.mqh index 20c0fe906..8b1b39d4a 100644 --- a/Indicators/Tick/Indi_TickMt.mqh +++ b/Indicators/Tick/Indi_TickMt.mqh @@ -52,8 +52,10 @@ class Indi_TickMt : public IndicatorTick { /** * Class constructor. */ - Indi_TickMt(IndiTickMtParams &_p, IndicatorData *_indi_src = NULL) - : IndicatorTick(_p, IndicatorDataParams::GetInstance(3, TYPE_DOUBLE), _indi_src){}; + Indi_TickMt(IndiTickMtParams &_p, ENUM_IDATA_SOURCE_TYPE _idstype = IDATA_BUILTIN, IndicatorData *_indi_src = NULL, + int _indi_src_mode = 0) + : IndicatorTick(_p, IndicatorDataParams::GetInstance(3, TYPE_DOUBLE, _idstype), + _indi_src){}; Indi_TickMt(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT, int _shift = 0, string _name = "") : IndicatorTick(INDI_TICK, _tf, _shift, _name) {} diff --git a/tests/DrawIndicatorTest.mq5 b/tests/DrawIndicatorTest.mq5 index 85e54b041..2770d7db5 100644 --- a/tests/DrawIndicatorTest.mq5 +++ b/tests/DrawIndicatorTest.mq5 @@ -98,7 +98,7 @@ bool InitIndicators() { // Moving Average. IndiMAParams ma_params(13, 10, MODE_SMA, PRICE_OPEN); - IndicatorBase *indi_ma = new Indi_MA(ma_params); + IndicatorData *indi_ma = new Indi_MA(ma_params); indis.Set(INDI_MA, indi_ma); // Relative Strength Index (RSI). @@ -109,40 +109,40 @@ bool InitIndicators() { // Demo/Dummy Indicator. IndiDemoParams demo_params; - IndicatorBase *indi_demo = new Indi_Demo(demo_params); + IndicatorData *indi_demo = new Indi_Demo(demo_params); indis.Set(INDI_DEMO, indi_demo); // Current Price (used by custom indicators) . PriceIndiParams price_params(); price_params.SetDraw(clrGreenYellow); - IndicatorBase *indi_price = new Indi_Price(price_params); + IndicatorData *indi_price = new Indi_Price(price_params); indis.Set(INDI_PRICE, indi_price); + /* @fixme: Array out of range. // Bollinger Bands over Price indicator. PriceIndiParams price_params_4_bands(); - IndicatorBase *indi_price_4_bands = new Indi_Price(price_params_4_bands); + IndicatorData *indi_price_4_bands = new Indi_Price(price_params_4_bands); IndiBandsParams bands_on_price_params(); bands_on_price_params.SetDraw(clrCadetBlue); - // bands_on_price_params.SetDataSource(indi_price_4_bands, true, INDI_PRICE_MODE_OPEN); - indis.Set(INDI_BANDS_ON_PRICE, new Indi_Bands(bands_on_price_params, indi_price_4_bands, true)); + indis.Set(INDI_BANDS_ON_PRICE, new Indi_Bands(bands_on_price_params, IDATA_INDICATOR, indi_price_4_bands)); // Moving Average (MA) over Price indicator. PriceIndiParams price_params_4_ma(); - IndicatorBase *indi_price_4_ma = new Indi_Price(price_params_4_ma); + IndicatorData *indi_price_4_ma = new Indi_Price(price_params_4_ma); IndiMAParams ma_on_price_params(); ma_on_price_params.SetDraw(clrYellowGreen); - // ma_on_price_params.SetDataSource(indi_price_4_ma, true, INDI_PRICE_MODE_OPEN); ma_on_price_params.SetIndicatorType(INDI_MA_ON_PRICE); - IndicatorBase *indi_ma_on_price = new Indi_MA(ma_on_price_params, indi_price_4_ma); + IndicatorData *indi_ma_on_price = new Indi_MA(ma_on_price_params, IDATA_INDICATOR, indi_price_4_ma); indis.Set(INDI_MA_ON_PRICE, indi_ma_on_price); // Relative Strength Index (RSI) over Price indicator. PriceIndiParams price_params_4_rsi(); - IndicatorBase *indi_price_4_rsi = new Indi_Price(price_params_4_rsi); + IndicatorData *indi_price_4_rsi = new Indi_Price(price_params_4_rsi); IndiRSIParams rsi_on_price_params(); - // rsi_on_price_params.SetDataSource(indi_price_4_rsi, true, INDI_PRICE_MODE_OPEN); rsi_on_price_params.SetDraw(clrBisque, 1); - indis.Set(INDI_RSI_ON_PRICE, indi_price_4_rsi); + IndicatorBase *indi_rsi_on_price = new Indi_RSI(rsi_on_price_params, IDATA_INDICATOR, indi_price_4_rsi); + indis.Set(INDI_RSI_ON_PRICE, indi_rsi_on_price); + */ return _LastError == ERR_NO_ERROR; } diff --git a/tests/IndicatorsTest.mq5 b/tests/IndicatorsTest.mq5 index d37403b81..6ec22c545 100644 --- a/tests/IndicatorsTest.mq5 +++ b/tests/IndicatorsTest.mq5 @@ -177,9 +177,11 @@ bool InitIndicators() { indis.Push(indi_bands); // Bollinger Bands over RSI. + /* @todo: Convert into new syntax. IndiBandsParams bands_over_rsi_params(20, 2, 0, PRICE_OPEN); // bands_over_rsi_params.SetDataSource(INDI_RSI); indis.Push(new Indi_Bands(bands_over_rsi_params)); + */ // Bears Power. IndiBearsPowerParams bears_params(13, PRICE_CLOSE); @@ -263,9 +265,11 @@ bool InitIndicators() { indis.Push(new Indi_RSI(rsi_params)); // Relative Strength Index (RSI). + /* @todo: Convert into new syntax. IndiRSIParams rsi_over_blt_stddev_params(); // rsi_over_blt_stddev_params.SetDataSource(INDI_STDDEV); indis.Push(new Indi_RSI(rsi_over_blt_stddev_params)); + */ // Relative Vigor Index (RVI). IndiRVIParams rvi_params(14); @@ -284,8 +288,7 @@ bool InitIndicators() { IndiStdDevParams stddev_on_price_params(); stddev_on_price_params.SetDraw(clrBlue, 1); - Ref indi_stddev_on_price = new Indi_StdDev(stddev_on_price_params); - indi_stddev_on_price.Ptr().SetDataSource(indi_price_for_stdev.Ptr(), PRICE_OPEN); + Ref indi_stddev_on_price = new Indi_StdDev(stddev_on_price_params, IDATA_BUILTIN, indi_price_for_stdev.Ptr()); indis.Push(indi_stddev_on_price.Ptr()); // Stochastic Oscillator. @@ -316,8 +319,7 @@ bool InitIndicators() { Ref indi_price_4_bands = new Indi_Price(price_params_4_bands); IndiBandsParams bands_on_price_params(); bands_on_price_params.SetDraw(clrCadetBlue); - Ref indi_bands_on_price = new Indi_Bands(bands_on_price_params); - indi_bands_on_price.Ptr().SetDataSource(indi_price_4_bands.Ptr()); + Ref indi_bands_on_price = new Indi_Bands(bands_on_price_params, IDATA_BUILTIN, indi_price_4_bands.Ptr()); indis.Push(indi_bands_on_price.Ptr()); // Standard Deviation (StdDev) over MA(SMA). @@ -329,8 +331,7 @@ bool InitIndicators() { IndiStdDevParams stddev_params_on_ma_sma(13, 10); stddev_params_on_ma_sma.SetDraw(true, 1); - Ref indi_stddev_on_ma_sma = new Indi_StdDev(stddev_params_on_ma_sma); - indi_stddev_on_ma_sma.Ptr().SetDataSource(indi_ma_sma_for_stddev.Ptr()); + Ref indi_stddev_on_ma_sma = new Indi_StdDev(stddev_params_on_ma_sma, IDATA_BUILTIN, indi_ma_sma_for_stddev.Ptr()); indis.Push(indi_stddev_on_ma_sma.Ptr()); // Standard Deviation (StdDev) in SMA mode over Price. @@ -339,8 +340,7 @@ bool InitIndicators() { IndiStdDevParams stddev_sma_on_price_params(); stddev_sma_on_price_params.SetDraw(true, 1); - Ref indi_stddev_on_sma = new Indi_StdDev(stddev_sma_on_price_params); - indi_stddev_on_sma.Ptr().SetDataSource(indi_price_for_stddev_sma.Ptr()); + Ref indi_stddev_on_sma = new Indi_StdDev(stddev_sma_on_price_params, IDATA_BUILTIN, indi_price_for_stddev_sma.Ptr()); indis.Push(indi_stddev_on_sma.Ptr()); // Moving Average (MA) over Price indicator. @@ -349,8 +349,7 @@ bool InitIndicators() { IndiMAParams ma_on_price_params(13, 0, MODE_SMA, PRICE_OPEN, 0); ma_on_price_params.SetDraw(clrYellowGreen); ma_on_price_params.SetIndicatorType(INDI_MA_ON_PRICE); - Ref indi_ma_on_price = new Indi_MA(ma_on_price_params); - indi_ma_on_price.Ptr().SetDataSource(indi_price_4_ma.Ptr()); + Ref indi_ma_on_price = new Indi_MA(ma_on_price_params, IDATA_BUILTIN, indi_price_4_ma.Ptr()); indis.Push(indi_ma_on_price.Ptr()); // Commodity Channel Index (CCI) over Price indicator. @@ -358,8 +357,7 @@ bool InitIndicators() { Ref indi_price_4_cci = new Indi_Price(price_params_4_cci); IndiCCIParams cci_on_price_params(); cci_on_price_params.SetDraw(clrYellowGreen, 1); - Ref indi_cci_on_price = new Indi_CCI(cci_on_price_params); - indi_cci_on_price.Ptr().SetDataSource(indi_price_4_cci.Ptr()); + Ref indi_cci_on_price = new Indi_CCI(cci_on_price_params, IDATA_BUILTIN, indi_price_4_cci.Ptr()); indis.Push(indi_cci_on_price.Ptr()); // Envelopes over Price indicator. @@ -367,8 +365,7 @@ bool InitIndicators() { Ref indi_price_4_envelopes = new Indi_Price(price_params_4_envelopes); IndiEnvelopesParams env_on_price_params(); env_on_price_params.SetDraw(clrBrown); - Ref indi_envelopes_on_price = new Indi_Envelopes(env_on_price_params); - indi_envelopes_on_price.Ptr().SetDataSource(indi_price_4_envelopes.Ptr()); + Ref indi_envelopes_on_price = new Indi_Envelopes(env_on_price_params, IDATA_BUILTIN, indi_price_4_envelopes.Ptr()); indis.Push(indi_envelopes_on_price.Ptr()); // DEMA over Price indicator. @@ -376,16 +373,14 @@ bool InitIndicators() { Ref indi_price_4_dema = new Indi_Price(price_params_4_dema); IndiDEIndiMAParams dema_on_price_params(13, 2, PRICE_OPEN); dema_on_price_params.SetDraw(clrRed); - Ref indi_dema_on_price = new Indi_DEMA(dema_on_price_params); - indi_dema_on_price.Ptr().SetDataSource(indi_price_4_dema.Ptr()); + Ref indi_dema_on_price = new Indi_DEMA(dema_on_price_params, IDATA_BUILTIN, indi_price_4_dema.Ptr()); indis.Push(indi_dema_on_price.Ptr()); // Momentum over Price indicator. Ref indi_price_4_momentum = new Indi_Price(); IndiMomentumParams mom_on_price_params(); mom_on_price_params.SetDraw(clrDarkCyan); - Ref indi_momentum_on_price = new Indi_Momentum(mom_on_price_params); - indi_momentum_on_price.Ptr().SetDataSource(indi_price_4_momentum.Ptr(), 0); + Ref indi_momentum_on_price = new Indi_Momentum(mom_on_price_params, IDATA_BUILTIN, indi_price_4_momentum.Ptr()); indis.Push(indi_momentum_on_price.Ptr()); // Relative Strength Index (RSI) over Price indicator. @@ -393,26 +388,22 @@ bool InitIndicators() { Ref indi_price_4_rsi = new Indi_Price(price_params_4_rsi); IndiRSIParams rsi_on_price_params(); rsi_on_price_params.SetDraw(clrBisque, 1); - Ref indi_rsi_on_price = new Indi_RSI(rsi_on_price_params); - indi_rsi_on_price.Ptr().SetDataSource(indi_price_4_rsi.Ptr()); + Ref indi_rsi_on_price = new Indi_RSI(rsi_on_price_params, IDATA_BUILTIN, indi_price_4_rsi.Ptr()); indis.Push(indi_rsi_on_price.Ptr()); - // Drawer (socket-based) indicator over RSI over Price. #ifndef __MQL4__ // @fixme: Fix it for MQL4. + // Drawer (socket-based) indicator over RSI over Price. IndiDrawerParams drawer_params(14, /*unused*/ PRICE_OPEN); drawer_params.SetDraw(clrBisque, 0); - // drawer_params.SetMaxModes(rsi_on_price_params.GetMaxModes()); - Ref indi_drawer_on_rsi = new Indi_Drawer(drawer_params); - indi_drawer_on_rsi.Ptr().SetDataSource(indi_rsi_on_price.Ptr(), PRICE_OPEN); + Ref indi_drawer_on_rsi = new Indi_Drawer(drawer_params, IDATA_BUILTIN, indi_rsi_on_price.Ptr()); indis.Push(indi_drawer_on_rsi.Ptr()); #endif // Applied Price over OHCL indicator. IndiAppliedPriceParams applied_price_params(); applied_price_params.SetDraw(clrAquamarine, 0); - IndiOHLCParams applied_price_ohlc_params; - Ref indi_applied_price_on_price = new Indi_AppliedPrice(applied_price_params); - indi_applied_price_on_price.Ptr().SetDataSource(new Indi_OHLC(applied_price_ohlc_params), PRICE_TYPICAL); + IndiOHLCParams applied_price_ohlc_params(PRICE_TYPICAL); + Ref indi_applied_price_on_price = new Indi_AppliedPrice(applied_price_params, IDATA_INDICATOR, new Indi_OHLC(applied_price_ohlc_params)); indis.Push(indi_applied_price_on_price.Ptr()); // ADXW. @@ -523,16 +514,14 @@ bool InitIndicators() { IndiMathParams math_params(MATH_OP_SUB, BAND_UPPER, BAND_LOWER, 0, 0); math_params.SetDraw(clrBlue); math_params.SetName("Bands(UP - LO)"); - Ref indi_math_1 = new Indi_Math(math_params); - indi_math_1.Ptr().SetDataSource(indi_bands.Ptr(), 0); + Ref indi_math_1 = new Indi_Math(math_params, IDATA_INDICATOR, indi_bands.Ptr()); indis.Push(indi_math_1.Ptr()); // Math (specialized indicator) via custom math method. IndiMathParams math_custom_params(MathCustomOp, BAND_UPPER, BAND_LOWER, 0, 0); math_custom_params.SetDraw(clrBeige); math_custom_params.SetName("Bands(Custom math fn)"); - Ref indi_math_2 = new Indi_Math(math_custom_params); - indi_math_2.Ptr().SetDataSource(indi_bands.Ptr(), 0); + Ref indi_math_2 = new Indi_Math(math_custom_params, IDATA_INDICATOR, indi_bands.Ptr()); indis.Push(indi_math_2.Ptr()); // RS (Math-based) indicator. From b26dfa50dbc3e7b9ae0b44df12c71650c1c47750 Mon Sep 17 00:00:00 2001 From: kenorb Date: Mon, 27 Jun 2022 01:32:23 +0100 Subject: [PATCH 81/81] 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. */