From b12160cb5aa5ca4d6866f4beb6584b103bca332b Mon Sep 17 00:00:00 2001 From: kenorb Date: Sat, 2 Sep 2023 22:42:20 +0100 Subject: [PATCH] Implements initial strategy logic --- README.md | 3 +- Stg_MA_Cross_Shift.mq5 | 2 +- Stg_MA_Cross_Shift.mqh | 134 +++++++++++++++++++++++++++++++---------- 3 files changed, 104 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 7e04e33..f0c7144 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ [![License][license-image]][license-link] [![Edit][gh-edit-badge]][gh-edit-link] -Strategy based on the moving average price indicators implementing shifted cross signal. +Strategy based on the moving average price indicators +implementing shifted cross signal. ## Dependencies diff --git a/Stg_MA_Cross_Shift.mq5 b/Stg_MA_Cross_Shift.mq5 index 1d8b12a..e4b2fd6 100644 --- a/Stg_MA_Cross_Shift.mq5 +++ b/Stg_MA_Cross_Shift.mq5 @@ -59,7 +59,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_MA_Cross_Shift.mqh b/Stg_MA_Cross_Shift.mqh index ba1a777..6c304dc 100644 --- a/Stg_MA_Cross_Shift.mqh +++ b/Stg_MA_Cross_Shift.mqh @@ -21,12 +21,12 @@ INPUT_GROUP("MA Cross Shift strategy: main strategy params"); INPUT ENUM_STG_MA_CROSS_SHIFT_TYPE MA_Cross_Shift_Type = STG_MA_CROSS_SHIFT_TYPE_MA; // Indicator MA type INPUT_GROUP("MA Cross Shift strategy: strategy params"); INPUT float MA_Cross_Shift_LotSize = 0; // Lot size -INPUT int MA_Cross_Shift_SignalOpenMethod = 1; // Signal open method (-127-127) -INPUT float MA_Cross_Shift_SignalOpenLevel = 0.2f; // Signal open level +INPUT int MA_Cross_Shift_SignalOpenMethod = 0; // Signal open method (-127-127) +INPUT float MA_Cross_Shift_SignalOpenLevel = 0.0f; // Signal open level INPUT int MA_Cross_Shift_SignalOpenFilterMethod = 32; // Signal open filter method INPUT int MA_Cross_Shift_SignalOpenFilterTime = 3; // Signal open filter time INPUT int MA_Cross_Shift_SignalOpenBoostMethod = 0; // Signal open boost method -INPUT int MA_Cross_Shift_SignalCloseMethod = 1; // Signal close method (-127-127) +INPUT int MA_Cross_Shift_SignalCloseMethod = 0; // Signal close method (-127-127) INPUT int MA_Cross_Shift_SignalCloseFilter = 0; // Signal close filter (-127-127) INPUT float MA_Cross_Shift_SignalCloseLevel = 0.0f; // Signal close level INPUT int MA_Cross_Shift_PriceStopMethod = 1; // Price stop method (0-127) @@ -43,18 +43,21 @@ INPUT int MA_Cross_Shift_Indi_AMA_InpFastPeriodEMA = 4; INPUT int MA_Cross_Shift_Indi_AMA_InpSlowPeriodEMA = 30; // Slow EMA period INPUT int MA_Cross_Shift_Indi_AMA_InpShiftAMA = 4; // AMA shift INPUT int MA_Cross_Shift_Indi_AMA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_AMA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_AMA_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: DEMA indicator params"); INPUT int MA_Cross_Shift_Indi_DEMA_Period = 25; // Period INPUT int MA_Cross_Shift_Indi_DEMA_MA_Shift = 6; // MA Shift INPUT ENUM_APPLIED_PRICE MA_Cross_Shift_Indi_DEMA_Applied_Price = PRICE_TYPICAL; // Applied Price -INPUT int MA_Cross_Shift_Indi_DEMA_Shift = 0; // DEMA Shift +INPUT int MA_Cross_Shift_Indi_DEMA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_DEMA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_DEMA_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: FrAMA indicator params"); -input int MA_Cross_Shift_Indi_FrAMA_Period = 10; // Period +INPUT int MA_Cross_Shift_Indi_FrAMA_Period = 10; // Period INPUT ENUM_APPLIED_PRICE MA_Cross_Shift_Indi_FrAMA_Applied_Price = PRICE_MEDIAN; // Applied Price INPUT int MA_Cross_Shift_Indi_FrAMA_MA_Shift = 0; // MA Shift -input int MA_Cross_Shift_Indi_FrAMA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_FrAMA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_FrAMA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_FrAMA_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: Ichimoku indicator params"); // INPUT ENUM_ICHIMOKU_LINE MA_Cross_Shift_Indi_Ichimoku_MA_Line = LINE_TENKANSEN; // Ichimoku line for MA @@ -62,6 +65,7 @@ INPUT int MA_Cross_Shift_Indi_Ichimoku_Period_Tenkan_Sen = 30; INPUT int MA_Cross_Shift_Indi_Ichimoku_Period_Kijun_Sen = 10; // Period Kijun Sen INPUT int MA_Cross_Shift_Indi_Ichimoku_Period_Senkou_Span_B = 30; // Period Senkou Span B INPUT int MA_Cross_Shift_Indi_Ichimoku_Shift = 1; // Shift +INPUT int MA_Cross_Shift_Indi_Ichimoku_Shift2 = 1; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_Ichimoku_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: MA indicator params"); INPUT int MA_Cross_Shift_Indi_MA_Period = 26; // Period @@ -69,34 +73,40 @@ INPUT int MA_Cross_Shift_Indi_MA_MA_Shift = 0; INPUT ENUM_MA_METHOD MA_Cross_Shift_Indi_MA_Method = MODE_LWMA; // MA Method INPUT ENUM_APPLIED_PRICE MA_Cross_Shift_Indi_MA_Applied_Price = PRICE_WEIGHTED; // Applied Price INPUT int MA_Cross_Shift_Indi_MA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_MA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_MA_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: Price Channel indicator params"); INPUT int MA_Cross_Shift_Indi_PriceChannel_Period = 26; // Period INPUT int MA_Cross_Shift_Indi_PriceChannel_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_PriceChannel_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_PriceChannel_SourceType = IDATA_ICUSTOM; // Source type INPUT_GROUP("MA Cross Shift strategy: SAR indicator params"); INPUT float MA_Cross_Shift_Indi_SAR_Step = 0.04f; // Step INPUT float MA_Cross_Shift_Indi_SAR_Maximum_Stop = 0.4f; // Maximum stop INPUT int MA_Cross_Shift_Indi_SAR_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_SAR_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_SAR_SourceType = IDATA_ICUSTOM; // Source type INPUT_GROUP("MA Cross Shift strategy: TEMA indicator params"); INPUT int MA_Cross_Shift_Indi_TEMA_Period = 10; // Period INPUT int MA_Cross_Shift_Indi_TEMA_MA_Shift = 0; // MA Shift INPUT ENUM_APPLIED_PRICE MA_Cross_Shift_Indi_TEMA_Applied_Price = PRICE_WEIGHTED; // Applied Price INPUT int MA_Cross_Shift_Indi_TEMA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_TEMA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_TEMA_SourceType = IDATA_BUILTIN; // Source type INPUT_GROUP("MA Cross Shift strategy: VIDYA indicator params"); -input int MA_Cross_Shift_Indi_VIDYA_Period = 30; // Period -input int MA_Cross_Shift_Indi_VIDYA_MA_Period = 20; // MA Period +INPUT int MA_Cross_Shift_Indi_VIDYA_Period = 30; // Period +INPUT int MA_Cross_Shift_Indi_VIDYA_MA_Period = 20; // MA Period INPUT int MA_Cross_Shift_Indi_VIDYA_MA_Shift = 1; // MA Shift INPUT ENUM_APPLIED_PRICE MA_Cross_Shift_Indi_VIDYA_Applied_Price = PRICE_WEIGHTED; // Applied Price -input int MA_Cross_Shift_Indi_VIDYA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_VIDYA_Shift = 0; // Shift +INPUT int MA_Cross_Shift_Indi_VIDYA_Shift2 = 10; // Shift 2 INPUT ENUM_IDATA_SOURCE_TYPE MA_Cross_Shift_Indi_VIDYA_SourceType = IDATA_BUILTIN; // Source type // Structs. // Defines struct with default user strategy values. struct Stg_MA_Cross_Shift_Params_Defaults : StgParams { + uint shift1, shift2; Stg_MA_Cross_Shift_Params_Defaults() : StgParams(::MA_Cross_Shift_SignalOpenMethod, ::MA_Cross_Shift_SignalOpenFilterMethod, ::MA_Cross_Shift_SignalOpenLevel, ::MA_Cross_Shift_SignalOpenBoostMethod, @@ -109,21 +119,30 @@ struct Stg_MA_Cross_Shift_Params_Defaults : StgParams { Set(STRAT_PARAM_OCT, MA_Cross_Shift_OrderCloseTime); Set(STRAT_PARAM_SOFT, MA_Cross_Shift_SignalOpenFilterTime); } + // Getters. + uint GetShift1() { return shift1; } + uint GetShift2() { return shift2; } + // Setters. + void SetShift1(uint _value) { shift1 = _value; } + void SetShift2(uint _value) { shift2 = _value; } }; -class Stg_MA : public Strategy { +class Stg_MA_Cross_Shift : public Strategy { + protected: + Stg_MA_Cross_Shift_Params_Defaults ssparams; + public: - Stg_MA(StgParams &_sparams, TradeParams &_tparams, ChartParams &_cparams, string _name = "") + Stg_MA_Cross_Shift(StgParams &_sparams, TradeParams &_tparams, ChartParams &_cparams, string _name = "") : Strategy(_sparams, _tparams, _cparams, _name) {} - static Stg_MA *Init(ENUM_TIMEFRAMES _tf = NULL, EA *_ea = NULL) { + static Stg_MA_Cross_Shift *Init(ENUM_TIMEFRAMES _tf = NULL, EA *_ea = NULL) { // Initialize strategy initial values. Stg_MA_Cross_Shift_Params_Defaults stg_ma_defaults; StgParams _stg_params(stg_ma_defaults); // Initialize Strategy instance. ChartParams _cparams(_tf, _Symbol); TradeParams _tparams; - Strategy *_strat = new Stg_MA(_stg_params, _tparams, _cparams, "MA"); + Strategy *_strat = new Stg_MA_Cross_Shift(_stg_params, _tparams, _cparams, "MA"); return _strat; } @@ -141,6 +160,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_AMA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_AMA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_AMA_Shift2); + SetIndicator(new Indi_AMA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_AMA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_AMA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_DEMA: // DEMA @@ -150,6 +173,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_DEMA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_DEMA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_DEMA_Shift2); + SetIndicator(new Indi_DEMA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_DEMA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_DEMA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_FRAMA: // FrAMA @@ -159,6 +186,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_FrAMA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_FrAMA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_FrAMA_Shift2); + SetIndicator(new Indi_FrAMA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_FrAMA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_FrAMA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_ICHIMOKU: // Ichimoku @@ -169,6 +200,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_Ichimoku_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_Ichimoku(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_Ichimoku_Shift2); + SetIndicator(new Indi_Ichimoku(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_Ichimoku_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_Ichimoku_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_MA: // MA @@ -179,6 +214,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_MA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_MA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_MA_Shift2); + SetIndicator(new Indi_MA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_MA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_MA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_PRICE_CHANNEL: // Price Channel @@ -188,6 +227,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_PriceChannel_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_PriceChannel(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_PriceChannel_Shift2); + SetIndicator(new Indi_PriceChannel(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_PriceChannel_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_PriceChannel_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_SAR: // SAR @@ -197,6 +240,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_SAR_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_SAR(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_SAR_Shift2); + SetIndicator(new Indi_SAR(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_SAR_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_SAR_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_TEMA: // TEMA @@ -206,6 +253,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_TEMA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_TEMA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_TEMA_Shift2); + SetIndicator(new Indi_TEMA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_TEMA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_TEMA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_VIDYA: // VIDYA @@ -216,6 +267,10 @@ class Stg_MA : public Strategy { _indi_params.SetDataSourceType(::MA_Cross_Shift_Indi_VIDYA_SourceType); _indi_params.SetTf(Get(STRAT_PARAM_TF)); SetIndicator(new Indi_VIDYA(_indi_params), ::MA_Cross_Shift_Type); + _indi_params.SetShift(::MA_Cross_Shift_Indi_VIDYA_Shift2); + SetIndicator(new Indi_VIDYA(_indi_params), ::MA_Cross_Shift_Type + 1); + ssparams.SetShift1(MA_Cross_Shift_Indi_VIDYA_Shift); + ssparams.SetShift2(MA_Cross_Shift_Indi_VIDYA_Shift2); break; } case STG_MA_CROSS_SHIFT_TYPE_0_NONE: // (None) @@ -228,41 +283,54 @@ class Stg_MA : public Strategy { * Check strategy's opening signal. */ bool SignalOpen(ENUM_ORDER_TYPE _cmd, int _method = 0, float _level = 0.0f, int _shift = 0) { - Chart *_chart = trade.GetChart(); - IndicatorBase *_indi = GetIndicator(::MA_Cross_Shift_Type); - uint _ishift = _shift; // @todo: _indi.GetShift(); + IndicatorBase *_indi1 = GetIndicator(::MA_Cross_Shift_Type); + IndicatorBase *_indi2 = GetIndicator(::MA_Cross_Shift_Type + 1); + // uint _ishift1 = _indi1.GetParams().GetShift(); // @todo: Convert into Get(). + // uint _ishift2 = _indi2.GetParams().GetShift(); // @todo: Convert into Get(). + uint _ishift1 = ssparams.GetShift1(); + uint _ishift2 = ssparams.GetShift2(); // bool _result = _indi.GetFlag(INDI_ENTRY_FLAG_IS_VALID, _shift); // @fixme bool _result = true; if (!_result) { // Returns false when indicator data is not valid. return false; } - float _level_pips = (float)(_level * _chart.GetPipSize()); + // float _level_pips = (float)(_level * _chart.GetPipSize()); + double _value1 = _indi1[_ishift1][0]; + double _value2 = _indi2[_ishift2][0]; switch (_cmd) { case ORDER_TYPE_BUY: - _result &= _indi[_shift][0] >= _chart.GetOpen(_ishift) + _level_pips; - _result &= - _indi[_shift + 1][0] < _chart.GetOpen(_ishift + 1) || _indi[_shift + 2][0] < _chart.GetOpen(_ishift + 2); - _result &= _indi.IsIncreasing(1, 0, _shift); + // Buy signal. + _result &= _indi1.IsIncreasing(1, 0, _ishift1); + _result &= _indi1[_ishift1][0] > _indi2[_ishift2][0]; + _result &= _indi1[_ishift1 + 1][0] < _indi2[_ishift2 + 1][0]; + //_result &= Math::ChangeInPct(_indi1[_ishift1 + 1][0], _indi1[_ishift1][0], true) > _level; if (_result && _method != 0) { - if (METHOD(_method, 0)) _result &= _indi.IsIncreasing(1, 0, _shift + 1); - if (METHOD(_method, 1)) _result &= _indi.IsIncreasing(4, 0, _shift + 3); + if (METHOD(_method, 0)) _result &= _indi1[_ishift1][0] < _indi1[_ishift1 + 3][0]; + if (METHOD(_method, 1)) _result &= _indi2[_ishift2][0] < _indi2[_ishift2 + 3][0]; if (METHOD(_method, 2)) - _result &= fmax4(_indi[_shift][0], _indi[_shift + 1][0], _indi[_shift + 2][0], _indi[_shift + 3][0]) == - _indi[_shift][0]; + _result &= fmax4(_indi1[_ishift1][0], _indi1[_ishift1 + 1][0], _indi1[_ishift1 + 2][0], + _indi1[_ishift1 + 3][0]) == _indi1[_ishift1][0]; + if (METHOD(_method, 3)) + _result &= fmax4(_indi2[_ishift2][0], _indi2[_ishift2 + 1][0], _indi2[_ishift2 + 2][0], + _indi2[_ishift2 + 3][0]) == _indi2[_ishift2][0]; } break; case ORDER_TYPE_SELL: - _result &= _indi[_shift][0] <= _chart.GetOpen(_ishift) - _level_pips; - _result &= - _indi[_shift + 1][0] > _chart.GetOpen(_ishift + 1) || _indi[_shift + 2][0] > _chart.GetOpen(_ishift + 2); - _result &= _indi.IsDecreasing(1, 0, _shift); + // Sell signal. + _result &= _indi1.IsDecreasing(1, 0, _ishift1); + _result &= _indi1[_ishift1][0] < _indi2[_ishift2][0]; + _result &= _indi1[_ishift1 + 1][0] > _indi2[_ishift2 + 1][0]; + //_result &= Math::ChangeInPct(_indi1[_ishift1 + 1][0], _indi1[_ishift1][0], true) < _level; if (_result && _method != 0) { - if (METHOD(_method, 0)) _result &= _indi.IsDecreasing(1, 0, _shift + 1); - if (METHOD(_method, 1)) _result &= _indi.IsDecreasing(4, 0, _shift + 3); + if (METHOD(_method, 0)) _result &= _indi1[_ishift1][0] > _indi1[_ishift1 + 3][0]; + if (METHOD(_method, 1)) _result &= _indi2[_ishift2][0] > _indi2[_ishift2 + 3][0]; if (METHOD(_method, 2)) - _result &= fmin4(_indi[_shift][0], _indi[_shift + 1][0], _indi[_shift + 2][0], _indi[_shift + 3][0]) == - _indi[_shift][0]; + _result &= fmin4(_indi1[_ishift1][0], _indi1[_ishift1 + 1][0], _indi1[_ishift1 + 2][0], + _indi1[_ishift1 + 3][0]) == _indi1[_ishift1][0]; + if (METHOD(_method, 3)) + _result &= fmin4(_indi2[_ishift2][0], _indi2[_ishift2 + 1][0], _indi2[_ishift2 + 2][0], + _indi2[_ishift2 + 3][0]) == _indi2[_ishift2][0]; } break; }