diff --git a/Indicator/Indicator.h b/Indicator/Indicator.h index 17c2173ef..795fd7e74 100644 --- a/Indicator/Indicator.h +++ b/Indicator/Indicator.h @@ -32,11 +32,13 @@ struct IndicatorParams; #include "Indicator.enum.h" #include "Indicator.struct.h" #include "Indicator.struct.serialize.h" +#include "IndicatorCandle.enum.h" #include "IndicatorData.h" // Includes. #include "../Indicators/DrawIndicator.mqh" #include "../Math/Math.h" +#include "../Platform/Chart/Chart.define.h" #include "../Refs.mqh" #include "../Serializer/Serializer.h" #include "../Serializer/SerializerCsv.h" @@ -161,13 +163,19 @@ class Indicator : public IndicatorData { * Returns the highest bar's index (shift). */ int GetHighest(int mode, int count = WHOLE_ARRAY, int start_bar = 0) override { + if (GetCandle() != THIS_PTR) { + Alert("You can only use ", __FUNCTION__, " on the Candle-based indicator! ", GetFullName(), + " is not a Candle indicator."); + DebugBreak(); + return -1; + } + 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) { - IndicatorDataEntry _entry = GetEntry(shift); - double value = _entry.GetMax(GetModeCount()); + double value = GetValue((int)GetCandleIndicatorMode(mode), shift); if (value > max) { max = value; max_idx = shift; @@ -181,13 +189,19 @@ class Indicator : public IndicatorData { * Returns the lowest bar's index (shift). */ int GetLowest(int mode, int count = WHOLE_ARRAY, int start_bar = 0) override { + if (GetCandle() != THIS_PTR) { + Alert("You can only use ", __FUNCTION__, " on the Candle-based indicator! ", GetFullName(), + " is not a Candle indicator."); + DebugBreak(); + return -1; + } + 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) { - IndicatorDataEntry _entry = GetEntry(shift); - double value = _entry.GetMin(GetModeCount()); + double value = GetValue((int)GetCandleIndicatorMode(mode), shift); if (value < min) { min = value; min_idx = shift; @@ -197,6 +211,35 @@ class Indicator : public IndicatorData { return min_idx; } + /** + * Converts Series Array Indentifier into mode index to be retrieved from Candle indicator. + * + * Possible values: + * MODE_OPEN, MODE_LOW, MODE_HIGH, MODE_CLOSE, MODE_VOLUME, MODE_TIME. + */ + ENUM_INDI_CANDLE_MODE GetCandleIndicatorMode(int _series_array_id) { + switch (_series_array_id) { + case MODE_OPEN: + return INDI_CANDLE_MODE_PRICE_OPEN; + case MODE_LOW: + return INDI_CANDLE_MODE_PRICE_LOW; + case MODE_HIGH: + return INDI_CANDLE_MODE_PRICE_HIGH; + case MODE_CLOSE: + return INDI_CANDLE_MODE_PRICE_CLOSE; + case MODE_VOLUME: + case MODE_REAL_VOLUME: + return INDI_CANDLE_MODE_VOLUME; + case MODE_TIME: + return INDI_CANDLE_MODE_TIME; + default: + Alert("Unsupported mode ", IntegerToString(_series_array_id), ", for ", __FUNCTION__, ""); + DebugBreak(); + } + + return (ENUM_INDI_CANDLE_MODE)0; + } + /* Setters */ /** diff --git a/Indicator/IndicatorCandle.enum.h b/Indicator/IndicatorCandle.enum.h new file mode 100644 index 000000000..7a17aaf6f --- /dev/null +++ b/Indicator/IndicatorCandle.enum.h @@ -0,0 +1,48 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2024, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * 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 IndicatorCandle's enums. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Indicator modes. +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_TIME, + INDI_CANDLE_MODE_VOLUME, + FINAL_INDI_CANDLE_MODE_ENTRY, + // Following modes are dynamically calculated. + INDI_CANDLE_MODE_PRICE_MEDIAN, + INDI_CANDLE_MODE_PRICE_TYPICAL, + INDI_CANDLE_MODE_PRICE_WEIGHTED, +}; diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index c97d9a9d9..7d7fb0072 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -36,6 +36,7 @@ #include "../Storage/ValueStorage.time.h" #include "../Storage/ValueStorage.volume.h" #include "Indicator.h" +#include "IndicatorCandle.enum.h" #include "IndicatorCandle.provider.h" #include "IndicatorData.h" #include "TickBarCounter.h" @@ -44,23 +45,6 @@ #define INDI_CANDLE_HISTORY_SIZE 86400 #endif -// Indicator modes. -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_TIME, - INDI_CANDLE_MODE_VOLUME, - FINAL_INDI_CANDLE_MODE_ENTRY, - // Following modes are dynamically calculated. - INDI_CANDLE_MODE_PRICE_MEDIAN, - INDI_CANDLE_MODE_PRICE_TYPICAL, - INDI_CANDLE_MODE_PRICE_WEIGHTED, -}; - /** * Class to deal with candle indicators. */ diff --git a/Platform/Chart/Chart.define.h b/Platform/Chart/Chart.define.h index 653898359..d5d772d37 100644 --- a/Platform/Chart/Chart.define.h +++ b/Platform/Chart/Chart.define.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif /* Defines */ @@ -56,51 +56,55 @@ #define MN1B (1 << MN1) // Monthly #ifndef __MQL4__ -// Chart. -#define CHART_BAR 0 -#define CHART_CANDLE 1 -//--- -#ifndef MODE_ASCEND -#define MODE_ASCEND 0 -#endif -#ifndef MODE_DESCEND -#define MODE_DESCEND 1 -#endif -//--- -#define MODE_LOW 1 -#define MODE_HIGH 2 -// -- -#define MODE_OPEN 0 -#define MODE_CLOSE 3 -#define MODE_VOLUME 4 -#define MODE_REAL_VOLUME 5 -// -- -#define MODE_TIME 5 -#define MODE_BID 9 -#define MODE_ASK 10 -#define MODE_POINT 11 -#define MODE_DIGITS 12 -#define MODE_SPREAD 13 -#define MODE_STOPLEVEL 14 -#define MODE_LOTSIZE 15 -#define MODE_TICKVALUE 16 -#define MODE_TICKSIZE 17 -#define MODE_SWAPLONG 18 -#define MODE_SWAPSHORT 19 -#define MODE_STARTING 20 -#define MODE_EXPIRATION 21 -#define MODE_TRADEALLOWED 22 -#define MODE_TICK_SIZE 21 -#define MODE_TICK_VALUE 22 -#define MODE_MINLOT 23 -#define MODE_LOTSTEP 24 -#define MODE_MAXLOT 25 -#define MODE_SWAPTYPE 26 -#define MODE_PROFITCALCMODE 27 -#define MODE_MARGINCALCMODE 28 -#define MODE_MARGININIT 29 -#define MODE_MARGINMAINTENANCE 30 -#define MODE_MARGINHEDGED 31 -#define MODE_MARGINREQUIRED 32 -#define MODE_FREEZELEVEL 33 + // Chart. + #define CHART_BAR 0 + #define CHART_CANDLE 1 + //--- + #ifndef MODE_ASCEND + #define MODE_ASCEND 0 + #endif + #ifndef MODE_DESCEND + #define MODE_DESCEND 1 + #endif + //--- + #define MODE_LOW 1 + #define MODE_HIGH 2 + // -- + #define MODE_OPEN 0 + #define MODE_CLOSE 3 + #define MODE_VOLUME 4 + // -- + #define MODE_TIME \ + 6 // Used to retrieve time from Candle indicator. Changed value from 5 to 6 in order to prevent conflicts with + // MODE_REAL_VOLUME. + #define MODE_BID 9 + #define MODE_ASK 10 + #define MODE_POINT 11 + #define MODE_DIGITS 12 + #define MODE_SPREAD 13 + #define MODE_STOPLEVEL 14 + #define MODE_LOTSIZE 15 + #define MODE_TICKVALUE 16 + #define MODE_TICKSIZE 17 + #define MODE_SWAPLONG 18 + #define MODE_SWAPSHORT 19 + #define MODE_STARTING 20 + #define MODE_EXPIRATION 21 + #define MODE_TRADEALLOWED 22 + #define MODE_TICK_SIZE 21 + #define MODE_TICK_VALUE 22 + #define MODE_MINLOT 23 + #define MODE_LOTSTEP 24 + #define MODE_MAXLOT 25 + #define MODE_SWAPTYPE 26 + #define MODE_PROFITCALCMODE 27 + #define MODE_MARGINCALCMODE 28 + #define MODE_MARGININIT 29 + #define MODE_MARGINMAINTENANCE 30 + #define MODE_MARGINHEDGED 31 + #define MODE_MARGINREQUIRED 32 + #define MODE_FREEZELEVEL 33 +#else + // #ifdef __MQL4__ + #define MODE_REAL_VOLUME 7 #endif diff --git a/tests/StrategyTest-RSI.mq5 b/tests/StrategyTest-RSI.mq5 index 0ce6b299b..46783323f 100644 --- a/tests/StrategyTest-RSI.mq5 +++ b/tests/StrategyTest-RSI.mq5 @@ -70,8 +70,8 @@ class Stg_RSI : public Strategy { IndiRSIParams _iparams = _indi.GetParams(); double _trail = _level * Market().GetPipSize(); int _direction = Order::OrderDirection(_cmd, _mode); - return _direction > 0 ? (float)_indi.GetPrice(PRICE_HIGH, _indi.GetHighest(_iparams.GetPeriod() * 2)) - : (float)_indi.GetPrice(PRICE_LOW, _indi.GetLowest(_iparams.GetPeriod() * 2)); + return _direction > 0 ? (float)_indi.GetPrice(PRICE_HIGH, _indi.GetHighest(_iparams.GetPeriod() * 2)) + : (float)_indi.GetPrice(PRICE_LOW, _indi.GetLowest(_iparams.GetPeriod() * 2)); } virtual void OnPeriod(unsigned int _periods = DATETIME_NONE) {