From 0263e7bcb15368606a2f63d547f01177e9c35061 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sat, 2 Sep 2023 21:35:08 +0100 Subject: [PATCH 1/3] Renames Oscillator_Cross to Oscillator_Cross_Zero --- Stg_Oscillator_Cross.mq4 => Stg_Oscillator_Cross_Zero.mq4 | 4 ++-- Stg_Oscillator_Cross.mq5 => Stg_Oscillator_Cross_Zero.mq5 | 2 +- Stg_Oscillator_Cross.mqh => Stg_Oscillator_Cross_Zero.mqh | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename Stg_Oscillator_Cross.mq4 => Stg_Oscillator_Cross_Zero.mq4 (82%) rename Stg_Oscillator_Cross.mq5 => Stg_Oscillator_Cross_Zero.mq5 (98%) rename Stg_Oscillator_Cross.mqh => Stg_Oscillator_Cross_Zero.mqh (100%) diff --git a/Stg_Oscillator_Cross.mq4 b/Stg_Oscillator_Cross_Zero.mq4 similarity index 82% rename from Stg_Oscillator_Cross.mq4 rename to Stg_Oscillator_Cross_Zero.mq4 index 65d3d3e..a824483 100644 --- a/Stg_Oscillator_Cross.mq4 +++ b/Stg_Oscillator_Cross_Zero.mq4 @@ -6,8 +6,8 @@ /** * @file - * Implements Oscillator Cross strategy. + * Implements Oscillator Cross Zero strategy. */ // Includes the main code. -#include "Stg_Oscillator_Cross.mq5" +#include "Stg_Oscillator_Cross_Zero.mq5" diff --git a/Stg_Oscillator_Cross.mq5 b/Stg_Oscillator_Cross_Zero.mq5 similarity index 98% rename from Stg_Oscillator_Cross.mq5 rename to Stg_Oscillator_Cross_Zero.mq5 index d3257eb..ff1a57c 100644 --- a/Stg_Oscillator_Cross.mq5 +++ b/Stg_Oscillator_Cross_Zero.mq5 @@ -23,7 +23,7 @@ input ENUM_LOG_LEVEL Log_Level = V_INFO; // Log level. input bool Info_On_Chart = true; // Display info on chart. // Includes strategy. -#include "Stg_Oscillator_Cross.mqh" +#include "Stg_Oscillator_Cross_Zero.mqh" // Defines. #define ea_name "Strategy Oscillator_Cross" diff --git a/Stg_Oscillator_Cross.mqh b/Stg_Oscillator_Cross_Zero.mqh similarity index 100% rename from Stg_Oscillator_Cross.mqh rename to Stg_Oscillator_Cross_Zero.mqh From dade6a01187e1a88e377c89280aa402c49e3c951 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sat, 2 Sep 2023 21:38:39 +0100 Subject: [PATCH 2/3] Replaces Oscillator_Cross with Oscillator_Cross_Zero --- Stg_Oscillator_Cross_Zero.mq5 | 10 +- Stg_Oscillator_Cross_Zero.mqh | 225 +++++++++++++++++----------------- 2 files changed, 120 insertions(+), 115 deletions(-) diff --git a/Stg_Oscillator_Cross_Zero.mq5 b/Stg_Oscillator_Cross_Zero.mq5 index ff1a57c..be64de2 100644 --- a/Stg_Oscillator_Cross_Zero.mq5 +++ b/Stg_Oscillator_Cross_Zero.mq5 @@ -1,6 +1,6 @@ /** * @file - * Implements Oscillator Cross strategy. + * Implements Oscillator Cross Zero strategy. */ // Includes conditional compilation directives. @@ -26,10 +26,10 @@ input bool Info_On_Chart = true; // Display info on chart. #include "Stg_Oscillator_Cross_Zero.mqh" // Defines. -#define ea_name "Strategy Oscillator_Cross" +#define ea_name "Strategy Oscillator Cross Zero" #define ea_version "2.000" -#define ea_desc "Strategy based on EA31337 framework." -#define ea_link "https://github.com/EA31337/Strategy-Oscillator_Cross" +#define ea_desc "Strategy based on selected oscillator-type zero-crossable indicators." +#define ea_link "https://github.com/EA31337/Strategy-Oscillator_Cross_Zero" #define ea_author "EA31337 Ltd" // Properties. @@ -55,7 +55,7 @@ int OnInit() { bool _result = true; EAParams ea_params(__FILE__, Log_Level); ea = new EA(ea_params); - _result &= ea.StrategyAdd(Active_Tfs); + _result &= ea.StrategyAdd(Active_Tfs); return (_result ? INIT_SUCCEEDED : INIT_FAILED); } diff --git a/Stg_Oscillator_Cross_Zero.mqh b/Stg_Oscillator_Cross_Zero.mqh index 94cc0b5..b61bc10 100644 --- a/Stg_Oscillator_Cross_Zero.mqh +++ b/Stg_Oscillator_Cross_Zero.mqh @@ -1,87 +1,88 @@ /** * @file - * Implements Oscillator Cross strategy based on the Oscillator Cross indicator. + * Implements Oscillator Cross Zero strategy based on selected oscillator-type zero-crossable indicators. */ // Enums. -enum ENUM_STG_OSCILLATOR_CROSS_TYPE { - STG_OSCILLATOR_CROSS_TYPE_0_NONE = 0, // (None) - STG_OSCILLATOR_CROSS_TYPE_ADX, // ADX - STG_OSCILLATOR_CROSS_TYPE_ADXW, // ADXW - STG_OSCILLATOR_CROSS_TYPE_MACD, // MACD - STG_OSCILLATOR_CROSS_TYPE_RVI, // RVI: Relative Vigor Index +enum ENUM_STG_OSCILLATOR_CROSS_ZERO_TYPE { + STG_OSCILLATOR_CROSS_ZERO_TYPE_0_NONE = 0, // (None) + STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX, // ADX + STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW, // ADXW + STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD, // MACD + STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI, // RVI: Relative Vigor Index }; // User input params. -INPUT_GROUP("Oscillator Cross strategy: main strategy params"); -INPUT ENUM_STG_OSCILLATOR_CROSS_TYPE Oscillator_Cross_Type = STG_OSCILLATOR_CROSS_TYPE_ADXW; // Oscillator type -INPUT_GROUP("Oscillator Cross strategy: strategy params"); -INPUT float Oscillator_Cross_LotSize = 0; // Lot size -INPUT int Oscillator_Cross_SignalOpenMethod = 2; // Signal open method -INPUT float Oscillator_Cross_SignalOpenLevel = 10.0f; // Signal open level -INPUT int Oscillator_Cross_SignalOpenFilterMethod = 32; // Signal open filter method -INPUT int Oscillator_Cross_SignalOpenFilterTime = 3; // Signal open filter time (0-31) -INPUT int Oscillator_Cross_SignalOpenBoostMethod = 0; // Signal open boost method -INPUT int Oscillator_Cross_SignalCloseMethod = 0; // Signal close method -INPUT int Oscillator_Cross_SignalCloseFilter = 32; // Signal close filter (-127-127) -INPUT float Oscillator_Cross_SignalCloseLevel = 10.0f; // Signal close level -INPUT int Oscillator_Cross_PriceStopMethod = 0; // Price limit method -INPUT float Oscillator_Cross_PriceStopLevel = 2; // Price limit level -INPUT int Oscillator_Cross_TickFilterMethod = 32; // Tick filter method (0-255) -INPUT float Oscillator_Cross_MaxSpread = 4.0; // Max spread to trade (in pips) -INPUT short Oscillator_Cross_Shift = 0; // Shift -INPUT float Oscillator_Cross_OrderCloseLoss = 80; // Order close loss -INPUT float Oscillator_Cross_OrderCloseProfit = 80; // Order close profit -INPUT int Oscillator_Cross_OrderCloseTime = -30; // Order close time in mins (>0) or bars (<0) -INPUT_GROUP("Oscillator Cross strategy: ADX indicator params"); -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Indi_ADX_Fast_Line = LINE_PLUSDI; // Fast line -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Indi_ADX_Slow_Line = LINE_MINUSDI; // Slow line to cross -INPUT int Oscillator_Cross_Indi_ADX_Period = 16; // Averaging period -INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Indi_ADX_AppliedPrice = PRICE_TYPICAL; // Applied price -INPUT int Oscillator_Cross_Indi_ADX_Shift = 0; // Shift -INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Indi_ADX_SourceType = IDATA_BUILTIN; // Source type -INPUT_GROUP("Oscillator Cross strategy: ADXW indicator params"); -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Indi_ADXW_Fast_Line = LINE_PLUSDI; // Fast line -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Indi_ADXW_Slow_Line = LINE_MINUSDI; // Slow line to cross -INPUT int Oscillator_Cross_Indi_ADXW_Period = 16; // Averaging period -INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Indi_ADXW_AppliedPrice = PRICE_TYPICAL; // Applied price -INPUT int Oscillator_Cross_Indi_ADXW_Shift = 0; // Shift -INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Indi_ADXW_SourceType = IDATA_BUILTIN; // Source type +INPUT_GROUP("Oscillator Cross Zero strategy: main strategy params"); +INPUT ENUM_STG_OSCILLATOR_CROSS_ZERO_TYPE Oscillator_Cross_Zero_Type = + STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW; // Oscillator type +INPUT_GROUP("Oscillator Cross Zero strategy: strategy params"); +INPUT float Oscillator_Cross_Zero_LotSize = 0; // Lot size +INPUT int Oscillator_Cross_Zero_SignalOpenMethod = 2; // Signal open method +INPUT float Oscillator_Cross_Zero_SignalOpenLevel = 10.0f; // Signal open level +INPUT int Oscillator_Cross_Zero_SignalOpenFilterMethod = 32; // Signal open filter method +INPUT int Oscillator_Cross_Zero_SignalOpenFilterTime = 3; // Signal open filter time (0-31) +INPUT int Oscillator_Cross_Zero_SignalOpenBoostMethod = 0; // Signal open boost method +INPUT int Oscillator_Cross_Zero_SignalCloseMethod = 0; // Signal close method +INPUT int Oscillator_Cross_Zero_SignalCloseFilter = 32; // Signal close filter (-127-127) +INPUT float Oscillator_Cross_Zero_SignalCloseLevel = 10.0f; // Signal close level +INPUT int Oscillator_Cross_Zero_PriceStopMethod = 0; // Price limit method +INPUT float Oscillator_Cross_Zero_PriceStopLevel = 2; // Price limit level +INPUT int Oscillator_Cross_Zero_TickFilterMethod = 32; // Tick filter method (0-255) +INPUT float Oscillator_Cross_Zero_MaxSpread = 4.0; // Max spread to trade (in pips) +INPUT short Oscillator_Cross_Zero_Shift = 0; // Shift +INPUT float Oscillator_Cross_Zero_OrderCloseLoss = 80; // Order close loss +INPUT float Oscillator_Cross_Zero_OrderCloseProfit = 80; // Order close profit +INPUT int Oscillator_Cross_Zero_OrderCloseTime = -30; // Order close time in mins (>0) or bars (<0) +INPUT_GROUP("Oscillator Cross Zero strategy: ADX indicator params"); +INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADX_Fast_Line = LINE_PLUSDI; // Fast line +INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADX_Slow_Line = LINE_MINUSDI; // Slow line to cross +INPUT int Oscillator_Cross_Zero_Indi_ADX_Period = 16; // Averaging period +INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_ADX_AppliedPrice = PRICE_TYPICAL; // Applied price +INPUT int Oscillator_Cross_Zero_Indi_ADX_Shift = 0; // Shift +INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_ADX_SourceType = IDATA_BUILTIN; // Source type +INPUT_GROUP("Oscillator Cross Zero strategy: ADXW indicator params"); +INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADXW_Fast_Line = LINE_PLUSDI; // Fast line +INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADXW_Slow_Line = LINE_MINUSDI; // Slow line to cross +INPUT int Oscillator_Cross_Zero_Indi_ADXW_Period = 16; // Averaging period +INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_ADXW_AppliedPrice = PRICE_TYPICAL; // Applied price +INPUT int Oscillator_Cross_Zero_Indi_ADXW_Shift = 0; // Shift +INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_ADXW_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("Oscillator strategy: MACD indicator params"); -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Indi_MACD_Fast_Line = LINE_SIGNAL; // Fast line -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Indi_MACD_Slow_Line = LINE_MAIN; // Slow line -INPUT int Oscillator_Cross_Indi_MACD_Period_Fast = 6; // Period Fast -INPUT int Oscillator_Cross_Indi_MACD_Period_Slow = 34; // Period Slow -INPUT int Oscillator_Cross_Indi_MACD_Period_Signal = 10; // Period Signal -INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Indi_MACD_Applied_Price = PRICE_OPEN; // Applied Price -INPUT int Oscillator_Cross_Indi_MACD_Shift = 0; // Shift +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_MACD_Fast_Line = LINE_SIGNAL; // Fast line +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_MACD_Slow_Line = LINE_MAIN; // Slow line +INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Fast = 6; // Period Fast +INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Slow = 34; // Period Slow +INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Signal = 10; // Period Signal +INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_MACD_Applied_Price = PRICE_OPEN; // Applied Price +INPUT int Oscillator_Cross_Zero_Indi_MACD_Shift = 0; // Shift INPUT_GROUP("Oscillator strategy: RVI indicator params"); -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Indi_RVI_Fast_Line = LINE_SIGNAL; // Fast line -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Indi_RVI_Slow_Line = LINE_MAIN; // Slow line -INPUT unsigned int Oscillator_Cross_Indi_RVI_Period = 12; // Averaging period -INPUT int Oscillator_Cross_Indi_RVI_Shift = 0; // Shift -INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Indi_RVI_SourceType = IDATA_BUILTIN; // Source type +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_RVI_Fast_Line = LINE_SIGNAL; // Fast line +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_RVI_Slow_Line = LINE_MAIN; // Slow line +INPUT unsigned int Oscillator_Cross_Zero_Indi_RVI_Period = 12; // Averaging period +INPUT int Oscillator_Cross_Zero_Indi_RVI_Shift = 0; // Shift +INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_RVI_SourceType = IDATA_BUILTIN; // Source type // Structs. // Defines struct with default user strategy values. -struct Stg_Oscillator_Cross_Params_Defaults : StgParams { +struct Stg_Oscillator_Cross_Zero_Params_Defaults : StgParams { uint line_fast, line_slow; - Stg_Oscillator_Cross_Params_Defaults() - : StgParams(::Oscillator_Cross_SignalOpenMethod, ::Oscillator_Cross_SignalOpenFilterMethod, - ::Oscillator_Cross_SignalOpenLevel, ::Oscillator_Cross_SignalOpenBoostMethod, - ::Oscillator_Cross_SignalCloseMethod, ::Oscillator_Cross_SignalCloseFilter, - ::Oscillator_Cross_SignalCloseLevel, ::Oscillator_Cross_PriceStopMethod, - ::Oscillator_Cross_PriceStopLevel, ::Oscillator_Cross_TickFilterMethod, ::Oscillator_Cross_MaxSpread, - ::Oscillator_Cross_Shift), + Stg_Oscillator_Cross_Zero_Params_Defaults() + : StgParams(::Oscillator_Cross_Zero_SignalOpenMethod, ::Oscillator_Cross_Zero_SignalOpenFilterMethod, + ::Oscillator_Cross_Zero_SignalOpenLevel, ::Oscillator_Cross_Zero_SignalOpenBoostMethod, + ::Oscillator_Cross_Zero_SignalCloseMethod, ::Oscillator_Cross_Zero_SignalCloseFilter, + ::Oscillator_Cross_Zero_SignalCloseLevel, ::Oscillator_Cross_Zero_PriceStopMethod, + ::Oscillator_Cross_Zero_PriceStopLevel, ::Oscillator_Cross_Zero_TickFilterMethod, + ::Oscillator_Cross_Zero_MaxSpread, ::Oscillator_Cross_Zero_Shift), line_fast(0), line_slow(0) { - Set(STRAT_PARAM_LS, Oscillator_Cross_LotSize); - Set(STRAT_PARAM_OCL, Oscillator_Cross_OrderCloseLoss); - Set(STRAT_PARAM_OCP, Oscillator_Cross_OrderCloseProfit); - Set(STRAT_PARAM_OCT, Oscillator_Cross_OrderCloseTime); - Set(STRAT_PARAM_SOFT, Oscillator_Cross_SignalOpenFilterTime); + Set(STRAT_PARAM_LS, Oscillator_Cross_Zero_LotSize); + Set(STRAT_PARAM_OCL, Oscillator_Cross_Zero_OrderCloseLoss); + Set(STRAT_PARAM_OCP, Oscillator_Cross_Zero_OrderCloseProfit); + Set(STRAT_PARAM_OCT, Oscillator_Cross_Zero_OrderCloseTime); + Set(STRAT_PARAM_SOFT, Oscillator_Cross_Zero_SignalOpenFilterTime); } // Getters. uint GetLineFast() { return line_fast; } @@ -91,23 +92,24 @@ struct Stg_Oscillator_Cross_Params_Defaults : StgParams { void SetLineSlow(uint _value) { line_slow = _value; } }; -class Stg_Oscillator_Cross : public Strategy { +class Stg_Oscillator_Cross_Zero : public Strategy { protected: - Stg_Oscillator_Cross_Params_Defaults ssparams; + Stg_Oscillator_Cross_Zero_Params_Defaults ssparams; public: - Stg_Oscillator_Cross(StgParams &_sparams, TradeParams &_tparams, ChartParams &_cparams, string _name = "") + Stg_Oscillator_Cross_Zero(StgParams &_sparams, TradeParams &_tparams, ChartParams &_cparams, string _name = "") : Strategy(_sparams, _tparams, _cparams, _name) {} - static Stg_Oscillator_Cross *Init(ENUM_TIMEFRAMES _tf = NULL, EA *_ea = NULL) { + static Stg_Oscillator_Cross_Zero *Init(ENUM_TIMEFRAMES _tf = NULL, EA *_ea = NULL) { // Initialize strategy initial values. - Stg_Oscillator_Cross_Params_Defaults stg_oscillator_cross_defaults; - StgParams _stg_params(stg_oscillator_cross_defaults); + Stg_Oscillator_Cross_Zero_Params_Defaults stg_oscillator_cross_zero_defaults; + StgParams _stg_params(stg_oscillator_cross_zero_defaults); // Initialize Strategy instance. ChartParams _cparams(_tf, _Symbol); TradeParams _tparams; - Stg_Oscillator_Cross *_strat = new Stg_Oscillator_Cross(_stg_params, _tparams, _cparams, "Oscillator_Cross"); - _strat.ssparams = stg_oscillator_cross_defaults; + Stg_Oscillator_Cross_Zero *_strat = + new Stg_Oscillator_Cross_Zero(_stg_params, _tparams, _cparams, "Oscillator_Cross_Zero"); + _strat.ssparams = stg_oscillator_cross_zero_defaults; return _strat; } @@ -116,20 +118,20 @@ class Stg_Oscillator_Cross : public Strategy { */ bool IsValidEntry(IndicatorBase *_indi, int _shift = 0) { bool _result = true; - switch (Oscillator_Cross_Type) { - case STG_OSCILLATOR_CROSS_TYPE_ADX: + switch (Oscillator_Cross_Zero_Type) { + case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX: _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); break; - case STG_OSCILLATOR_CROSS_TYPE_ADXW: + case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW: _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); break; - case STG_OSCILLATOR_CROSS_TYPE_MACD: + case STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD: _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); break; - case STG_OSCILLATOR_CROSS_TYPE_RVI: + case STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI: _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); break; @@ -144,53 +146,56 @@ class Stg_Oscillator_Cross : public Strategy { */ void OnInit() { // Initialize indicators. - switch (Oscillator_Cross_Type) { - case STG_OSCILLATOR_CROSS_TYPE_ADX: // ADX + switch (Oscillator_Cross_Zero_Type) { + case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX: // ADX { - IndiADXParams _adx_params(::Oscillator_Cross_Indi_ADX_Period, ::Oscillator_Cross_Indi_ADX_AppliedPrice, - ::Oscillator_Cross_Indi_ADX_Shift); - _adx_params.SetDataSourceType(::Oscillator_Cross_Indi_ADX_SourceType); + IndiADXParams _adx_params(::Oscillator_Cross_Zero_Indi_ADX_Period, + ::Oscillator_Cross_Zero_Indi_ADX_AppliedPrice, + ::Oscillator_Cross_Zero_Indi_ADX_Shift); + _adx_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_ADX_SourceType); _adx_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_ADX(_adx_params), ::Oscillator_Cross_Type); + SetIndicator(new Indi_ADX(_adx_params), ::Oscillator_Cross_Zero_Type); // sparams.SetLineFast(0); // @todo: Fix Strategy to allow custom params stored in sparam. - ssparams.SetLineFast((uint)Oscillator_Cross_Indi_ADX_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Indi_ADX_Slow_Line); + ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_ADX_Fast_Line); + ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_ADX_Slow_Line); break; } - case STG_OSCILLATOR_CROSS_TYPE_ADXW: // ADXW + case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW: // ADXW { - IndiADXWParams _adxw_params(::Oscillator_Cross_Indi_ADXW_Period, ::Oscillator_Cross_Indi_ADXW_AppliedPrice, - ::Oscillator_Cross_Indi_ADXW_Shift); - _adxw_params.SetDataSourceType(::Oscillator_Cross_Indi_ADXW_SourceType); + IndiADXWParams _adxw_params(::Oscillator_Cross_Zero_Indi_ADXW_Period, + ::Oscillator_Cross_Zero_Indi_ADXW_AppliedPrice, + ::Oscillator_Cross_Zero_Indi_ADXW_Shift); + _adxw_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_ADXW_SourceType); _adxw_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_ADXW(_adxw_params), ::Oscillator_Cross_Type); + SetIndicator(new Indi_ADXW(_adxw_params), ::Oscillator_Cross_Zero_Type); // sparams.SetLineFast(0); // @todo: Fix Strategy to allow custom params stored in sparam. - ssparams.SetLineFast((uint)Oscillator_Cross_Indi_ADXW_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Indi_ADXW_Slow_Line); + ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_ADXW_Fast_Line); + ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_ADXW_Slow_Line); break; } - case STG_OSCILLATOR_CROSS_TYPE_MACD: // MACD + case STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD: // MACD { - IndiMACDParams _indi_params(::Oscillator_Cross_Indi_MACD_Period_Fast, ::Oscillator_Cross_Indi_MACD_Period_Slow, - ::Oscillator_Cross_Indi_MACD_Period_Signal, - ::Oscillator_Cross_Indi_MACD_Applied_Price, ::Oscillator_Cross_Indi_MACD_Shift); + IndiMACDParams _indi_params( + ::Oscillator_Cross_Zero_Indi_MACD_Period_Fast, ::Oscillator_Cross_Zero_Indi_MACD_Period_Slow, + ::Oscillator_Cross_Zero_Indi_MACD_Period_Signal, ::Oscillator_Cross_Zero_Indi_MACD_Applied_Price, + ::Oscillator_Cross_Zero_Indi_MACD_Shift); _indi_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_MACD(_indi_params), ::Oscillator_Cross_Type); - ssparams.SetLineFast((uint)Oscillator_Cross_Indi_MACD_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Indi_MACD_Slow_Line); + SetIndicator(new Indi_MACD(_indi_params), ::Oscillator_Cross_Zero_Type); + ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_MACD_Fast_Line); + ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_MACD_Slow_Line); break; } - case STG_OSCILLATOR_CROSS_TYPE_RVI: // RVI + case STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI: // RVI { - IndiRVIParams _indi_params(::Oscillator_Cross_Indi_RVI_Period, ::Oscillator_Cross_Indi_RVI_Shift); - _indi_params.SetDataSourceType(::Oscillator_Cross_Indi_RVI_SourceType); + IndiRVIParams _indi_params(::Oscillator_Cross_Zero_Indi_RVI_Period, ::Oscillator_Cross_Zero_Indi_RVI_Shift); + _indi_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_RVI_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_RVI(_indi_params), ::Oscillator_Cross_Type); - ssparams.SetLineFast((uint)Oscillator_Cross_Indi_RVI_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Indi_RVI_Slow_Line); + SetIndicator(new Indi_RVI(_indi_params), ::Oscillator_Cross_Zero_Type); + ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_RVI_Fast_Line); + ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_RVI_Slow_Line); break; } - case STG_OSCILLATOR_CROSS_TYPE_0_NONE: // (None) + case STG_OSCILLATOR_CROSS_ZERO_TYPE_0_NONE: // (None) default: break; } @@ -200,9 +205,9 @@ class Stg_Oscillator_Cross : public Strategy { * Check strategy's opening signal. */ bool SignalOpen(ENUM_ORDER_TYPE _cmd, int _method, float _level = 0.0f, int _shift = 0) { - IndicatorBase *_indi = GetIndicator(::Oscillator_Cross_Type); + IndicatorBase *_indi = GetIndicator(::Oscillator_Cross_Zero_Type); // uint _ishift = _indi.GetShift(); // @todo - bool _result = Oscillator_Cross_Type != STG_OSCILLATOR_CROSS_TYPE_0_NONE && IsValidEntry(_indi, _shift); + bool _result = Oscillator_Cross_Zero_Type != STG_OSCILLATOR_CROSS_ZERO_TYPE_0_NONE && IsValidEntry(_indi, _shift); if (!_result) { // Returns false when indicator data is not valid. return false; From d540f869654e58e417e86a9069304826aa435cad Mon Sep 17 00:00:00 2001 From: kenorb Date: Sat, 2 Sep 2023 21:57:02 +0100 Subject: [PATCH 3/3] Implements initial strategy trading logic --- .github/workflows/backtest.yml | 6 +- .github/workflows/compile.yml | 4 +- Stg_Oscillator_Cross_Zero.mqh | 119 +++++++++------------------------ 3 files changed, 37 insertions(+), 92 deletions(-) diff --git a/.github/workflows/backtest.yml b/.github/workflows/backtest.yml index 76757a6..8c8c061 100644 --- a/.github/workflows/backtest.yml +++ b/.github/workflows/backtest.yml @@ -37,14 +37,14 @@ jobs: include: . init-platform: true mt-version: 5.0.0.2361 - path: Stg_Oscillator_Cross.mq4 + path: Stg_Oscillator_Cross_Zero.mq4 verbose: true - name: Compile for MQL5 uses: fx31337/mql-compile-action@master with: include: . mt-version: 5.0.0.2515 - path: Stg_Oscillator_Cross.mq5 + path: Stg_Oscillator_Cross_Zero.mq5 verbose: true - name: List compiled files run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' @@ -75,7 +75,7 @@ jobs: OptFormatBrief: true OptFormatJson: true OptVerbose: true - TestExpert: "Stg_Oscillator_Cross" + TestExpert: "Stg_Oscillator_Cross_Zero" TestPeriod: M1 TestReportName: Report-${{ matrix.year }}-${{ matrix.month }} - name: Upload results diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 6dba81e..d769702 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -39,14 +39,14 @@ jobs: include: . init-platform: true mt-version: 5.0.0.2361 - path: Stg_Oscillator_Cross.mq4 + path: Stg_Oscillator_Cross_Zero.mq4 verbose: true - name: Compile for MQL5 uses: fx31337/mql-compile-action@master with: include: . mt-version: 5.0.0.2515 - path: Stg_Oscillator_Cross.mq5 + path: Stg_Oscillator_Cross_Zero.mq5 verbose: true - name: List compiled files run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' diff --git a/Stg_Oscillator_Cross_Zero.mqh b/Stg_Oscillator_Cross_Zero.mqh index b61bc10..d65ce7e 100644 --- a/Stg_Oscillator_Cross_Zero.mqh +++ b/Stg_Oscillator_Cross_Zero.mqh @@ -7,8 +7,6 @@ enum ENUM_STG_OSCILLATOR_CROSS_ZERO_TYPE { STG_OSCILLATOR_CROSS_ZERO_TYPE_0_NONE = 0, // (None) - STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX, // ADX - STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW, // ADXW STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD, // MACD STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI, // RVI: Relative Vigor Index }; @@ -16,17 +14,17 @@ enum ENUM_STG_OSCILLATOR_CROSS_ZERO_TYPE { // User input params. INPUT_GROUP("Oscillator Cross Zero strategy: main strategy params"); INPUT ENUM_STG_OSCILLATOR_CROSS_ZERO_TYPE Oscillator_Cross_Zero_Type = - STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW; // Oscillator type + STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI; // Oscillator type INPUT_GROUP("Oscillator Cross Zero strategy: strategy params"); INPUT float Oscillator_Cross_Zero_LotSize = 0; // Lot size -INPUT int Oscillator_Cross_Zero_SignalOpenMethod = 2; // Signal open method -INPUT float Oscillator_Cross_Zero_SignalOpenLevel = 10.0f; // Signal open level +INPUT int Oscillator_Cross_Zero_SignalOpenMethod = 0; // Signal open method +INPUT float Oscillator_Cross_Zero_SignalOpenLevel = 0.1f; // Signal open level INPUT int Oscillator_Cross_Zero_SignalOpenFilterMethod = 32; // Signal open filter method INPUT int Oscillator_Cross_Zero_SignalOpenFilterTime = 3; // Signal open filter time (0-31) INPUT int Oscillator_Cross_Zero_SignalOpenBoostMethod = 0; // Signal open boost method INPUT int Oscillator_Cross_Zero_SignalCloseMethod = 0; // Signal close method INPUT int Oscillator_Cross_Zero_SignalCloseFilter = 32; // Signal close filter (-127-127) -INPUT float Oscillator_Cross_Zero_SignalCloseLevel = 10.0f; // Signal close level +INPUT float Oscillator_Cross_Zero_SignalCloseLevel = 0.1f; // Signal close level INPUT int Oscillator_Cross_Zero_PriceStopMethod = 0; // Price limit method INPUT float Oscillator_Cross_Zero_PriceStopLevel = 2; // Price limit level INPUT int Oscillator_Cross_Zero_TickFilterMethod = 32; // Tick filter method (0-255) @@ -35,31 +33,15 @@ INPUT short Oscillator_Cross_Zero_Shift = 0; // Shift INPUT float Oscillator_Cross_Zero_OrderCloseLoss = 80; // Order close loss INPUT float Oscillator_Cross_Zero_OrderCloseProfit = 80; // Order close profit INPUT int Oscillator_Cross_Zero_OrderCloseTime = -30; // Order close time in mins (>0) or bars (<0) -INPUT_GROUP("Oscillator Cross Zero strategy: ADX indicator params"); -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADX_Fast_Line = LINE_PLUSDI; // Fast line -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADX_Slow_Line = LINE_MINUSDI; // Slow line to cross -INPUT int Oscillator_Cross_Zero_Indi_ADX_Period = 16; // Averaging period -INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_ADX_AppliedPrice = PRICE_TYPICAL; // Applied price -INPUT int Oscillator_Cross_Zero_Indi_ADX_Shift = 0; // Shift -INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_ADX_SourceType = IDATA_BUILTIN; // Source type -INPUT_GROUP("Oscillator Cross Zero strategy: ADXW indicator params"); -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADXW_Fast_Line = LINE_PLUSDI; // Fast line -INPUT ENUM_INDI_ADX_LINE Oscillator_Cross_Zero_Indi_ADXW_Slow_Line = LINE_MINUSDI; // Slow line to cross -INPUT int Oscillator_Cross_Zero_Indi_ADXW_Period = 16; // Averaging period -INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_ADXW_AppliedPrice = PRICE_TYPICAL; // Applied price -INPUT int Oscillator_Cross_Zero_Indi_ADXW_Shift = 0; // Shift -INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_ADXW_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("Oscillator strategy: MACD indicator params"); -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_MACD_Fast_Line = LINE_SIGNAL; // Fast line -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_MACD_Slow_Line = LINE_MAIN; // Slow line +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_MACD_Line_Signal = LINE_SIGNAL; // Signal line INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Fast = 6; // Period Fast INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Slow = 34; // Period Slow INPUT int Oscillator_Cross_Zero_Indi_MACD_Period_Signal = 10; // Period Signal INPUT ENUM_APPLIED_PRICE Oscillator_Cross_Zero_Indi_MACD_Applied_Price = PRICE_OPEN; // Applied Price INPUT int Oscillator_Cross_Zero_Indi_MACD_Shift = 0; // Shift INPUT_GROUP("Oscillator strategy: RVI indicator params"); -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_RVI_Fast_Line = LINE_SIGNAL; // Fast line -INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_RVI_Slow_Line = LINE_MAIN; // Slow line +INPUT ENUM_SIGNAL_LINE Oscillator_Cross_Zero_Indi_RVI_Line_Signal = LINE_SIGNAL; // Fast line INPUT unsigned int Oscillator_Cross_Zero_Indi_RVI_Period = 12; // Averaging period INPUT int Oscillator_Cross_Zero_Indi_RVI_Shift = 0; // Shift INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_RVI_SourceType = IDATA_BUILTIN; // Source type @@ -68,7 +50,7 @@ INPUT ENUM_IDATA_SOURCE_TYPE Oscillator_Cross_Zero_Indi_RVI_SourceType = IDATA_B // Defines struct with default user strategy values. struct Stg_Oscillator_Cross_Zero_Params_Defaults : StgParams { - uint line_fast, line_slow; + uint line_signal; Stg_Oscillator_Cross_Zero_Params_Defaults() : StgParams(::Oscillator_Cross_Zero_SignalOpenMethod, ::Oscillator_Cross_Zero_SignalOpenFilterMethod, ::Oscillator_Cross_Zero_SignalOpenLevel, ::Oscillator_Cross_Zero_SignalOpenBoostMethod, @@ -76,8 +58,7 @@ struct Stg_Oscillator_Cross_Zero_Params_Defaults : StgParams { ::Oscillator_Cross_Zero_SignalCloseLevel, ::Oscillator_Cross_Zero_PriceStopMethod, ::Oscillator_Cross_Zero_PriceStopLevel, ::Oscillator_Cross_Zero_TickFilterMethod, ::Oscillator_Cross_Zero_MaxSpread, ::Oscillator_Cross_Zero_Shift), - line_fast(0), - line_slow(0) { + line_signal(0) { Set(STRAT_PARAM_LS, Oscillator_Cross_Zero_LotSize); Set(STRAT_PARAM_OCL, Oscillator_Cross_Zero_OrderCloseLoss); Set(STRAT_PARAM_OCP, Oscillator_Cross_Zero_OrderCloseProfit); @@ -85,11 +66,9 @@ struct Stg_Oscillator_Cross_Zero_Params_Defaults : StgParams { Set(STRAT_PARAM_SOFT, Oscillator_Cross_Zero_SignalOpenFilterTime); } // Getters. - uint GetLineFast() { return line_fast; } - uint GetLineSlow() { return line_slow; } + uint GetLineSignal() { return line_signal; } // Setters. - void SetLineFast(uint _value) { line_fast = _value; } - void SetLineSlow(uint _value) { line_slow = _value; } + void SetLineSignal(uint _value) { line_signal = _value; } }; class Stg_Oscillator_Cross_Zero : public Strategy { @@ -119,14 +98,6 @@ class Stg_Oscillator_Cross_Zero : public Strategy { bool IsValidEntry(IndicatorBase *_indi, int _shift = 0) { bool _result = true; switch (Oscillator_Cross_Zero_Type) { - case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX: - _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && - dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); - break; - case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW: - _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && - dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); - break; case STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD: _result &= dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift) && dynamic_cast(_indi).GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift + 1); @@ -147,32 +118,6 @@ class Stg_Oscillator_Cross_Zero : public Strategy { void OnInit() { // Initialize indicators. switch (Oscillator_Cross_Zero_Type) { - case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADX: // ADX - { - IndiADXParams _adx_params(::Oscillator_Cross_Zero_Indi_ADX_Period, - ::Oscillator_Cross_Zero_Indi_ADX_AppliedPrice, - ::Oscillator_Cross_Zero_Indi_ADX_Shift); - _adx_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_ADX_SourceType); - _adx_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_ADX(_adx_params), ::Oscillator_Cross_Zero_Type); - // sparams.SetLineFast(0); // @todo: Fix Strategy to allow custom params stored in sparam. - ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_ADX_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_ADX_Slow_Line); - break; - } - case STG_OSCILLATOR_CROSS_ZERO_TYPE_ADXW: // ADXW - { - IndiADXWParams _adxw_params(::Oscillator_Cross_Zero_Indi_ADXW_Period, - ::Oscillator_Cross_Zero_Indi_ADXW_AppliedPrice, - ::Oscillator_Cross_Zero_Indi_ADXW_Shift); - _adxw_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_ADXW_SourceType); - _adxw_params.SetTf(Get(STRAT_PARAM_TF)); - SetIndicator(new Indi_ADXW(_adxw_params), ::Oscillator_Cross_Zero_Type); - // sparams.SetLineFast(0); // @todo: Fix Strategy to allow custom params stored in sparam. - ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_ADXW_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_ADXW_Slow_Line); - break; - } case STG_OSCILLATOR_CROSS_ZERO_TYPE_MACD: // MACD { IndiMACDParams _indi_params( @@ -181,8 +126,7 @@ class Stg_Oscillator_Cross_Zero : public Strategy { ::Oscillator_Cross_Zero_Indi_MACD_Shift); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_MACD(_indi_params), ::Oscillator_Cross_Zero_Type); - ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_MACD_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_MACD_Slow_Line); + ssparams.SetLineSignal((uint)Oscillator_Cross_Zero_Indi_MACD_Line_Signal); break; } case STG_OSCILLATOR_CROSS_ZERO_TYPE_RVI: // RVI @@ -191,8 +135,7 @@ class Stg_Oscillator_Cross_Zero : public Strategy { _indi_params.SetDataSourceType(::Oscillator_Cross_Zero_Indi_RVI_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_RVI(_indi_params), ::Oscillator_Cross_Zero_Type); - ssparams.SetLineFast((uint)Oscillator_Cross_Zero_Indi_RVI_Fast_Line); - ssparams.SetLineSlow((uint)Oscillator_Cross_Zero_Indi_RVI_Slow_Line); + ssparams.SetLineSignal((uint)Oscillator_Cross_Zero_Indi_RVI_Line_Signal); break; } case STG_OSCILLATOR_CROSS_ZERO_TYPE_0_NONE: // (None) @@ -212,35 +155,37 @@ class Stg_Oscillator_Cross_Zero : public Strategy { // Returns false when indicator data is not valid. return false; } - int _line_fast = (int)ssparams.GetLineFast(); - int _line_slow = (int)ssparams.GetLineSlow(); - double _value1 = _indi[_shift][_line_fast]; - double _value2 = _indi[_shift][_line_slow]; + int _mode_signal = (int)ssparams.GetLineSignal(); + double _value1 = _indi[_shift][_mode_signal]; + double _value2 = _indi[_shift + 1][_mode_signal] < 0; + ; switch (_cmd) { case ORDER_TYPE_BUY: // Buy signal. - _result &= _indi.IsIncreasing(1, _line_fast, _shift); - _result &= _indi[_shift][_line_fast] > _indi[_shift][_line_slow]; - _result &= _indi[_shift + 1][_line_fast] < _indi[_shift + 1][_line_slow]; - _result &= Math::ChangeInPct(_indi[_shift + 1][_line_fast], _indi[_shift][_line_fast], true) > _level; + _result &= _indi[_shift][_mode_signal] > 0; + _result &= _indi[_shift + 1][_mode_signal] < 0; + _result &= _indi.IsIncreasing(1, _mode_signal, _shift); + _result &= Math::ChangeInPct(_indi[_shift + 1][_mode_signal], _indi[_shift][_mode_signal], true) > _level; if (_result && _method != 0) { - _result &= _indi[_shift + 3][_line_fast] < _indi[_shift + 3][_line_slow]; + _result &= _indi[_shift + 3][_mode_signal] < 0; if (METHOD(_method, 1)) - _result &= fmax4(_indi[_shift][_line_fast], _indi[_shift + 1][_line_fast], _indi[_shift + 2][_line_fast], - _indi[_shift + 3][_line_fast]) == _indi[_shift][_line_fast]; + _result &= + fmax4(_indi[_shift][_mode_signal], _indi[_shift + 1][_mode_signal], _indi[_shift + 2][_mode_signal], + _indi[_shift + 3][_mode_signal]) == _indi[_shift][_mode_signal]; } break; case ORDER_TYPE_SELL: // Sell signal. - _result &= _indi.IsDecreasing(1, _line_fast, _shift); - _result &= _indi[_shift][_line_fast] < _indi[_shift][_line_slow]; - _result &= _indi[_shift + 1][_line_fast] > _indi[_shift + 1][_line_slow]; - _result &= Math::ChangeInPct(_indi[_shift + 1][_line_fast], _indi[_shift][_line_fast], true) < _level; + _result &= _indi[_shift][_mode_signal] < 0; + _result &= _indi[_shift + 1][_mode_signal] > 0; + _result &= _indi.IsDecreasing(1, _mode_signal, _shift); + _result &= Math::ChangeInPct(_indi[_shift + 1][_mode_signal], _indi[_shift][_mode_signal], true) < _level; if (_result && _method != 0) { - if (METHOD(_method, 0)) _result &= _indi[_shift + 3][_line_fast] > _indi[_shift + 3][_line_slow]; + if (METHOD(_method, 0)) _result &= _indi[_shift + 3][_mode_signal] > 0; if (METHOD(_method, 1)) - _result &= fmin4(_indi[_shift][_line_fast], _indi[_shift + 1][_line_fast], _indi[_shift + 2][_line_fast], - _indi[_shift + 3][_line_fast]) == _indi[_shift][_line_fast]; + _result &= + fmin4(_indi[_shift][_mode_signal], _indi[_shift + 1][_mode_signal], _indi[_shift + 2][_mode_signal], + _indi[_shift + 3][_mode_signal]) == _indi[_shift][_mode_signal]; } break; }