diff --git a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 index f9c37bf1..cf55b0ca 100644 --- a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 +++ b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 @@ -205,12 +205,23 @@ struct XTriggerBlockFilters bool filterBasedOnHKSignalBar; // Filter Based On HK Signal Bar ... // - int bosLoopback; // PV Based Filtering BOS Lookup ... + int bosLoopback; // PV Based Filtering BOS Lookup ... + + // bool forceSarSwitched; // SAR Switched on Sides for Filtering ... bool forceSarOnBothSide; // SAR Check on Both Sides for Filtering ... bool forceSarHasBreakout; // SAR Must Has Reversal Direction in Trigger Block ... bool forceSarHasReversalSide; // SAR Must Has Reversal Direction in Trigger Block ... + // + bool forceHasRSITrending; // RSI Must Has Trending ... + bool forceHasRSIVPattern; // RSI Must Has Pattern ... + bool forceHasRSICrossing; // RSI Must Has Crossing Levels ... + + // + bool forceHasADXTrending; // ADX Must Trending ... + bool forceHasADXCrossing; // ADX Must Has Crossing +DI/-DI ... + // // Constructor(s) ... XTriggerBlockFilters() @@ -239,11 +250,22 @@ struct XTriggerBlockFilters // bosLoopback = 0; + + // forceSarSwitched = false; forceSarOnBothSide = false; forceSarHasBreakout = false; forceSarHasReversalSide = false; + // + forceHasRSITrending = false; + forceHasRSIVPattern = false; + forceHasRSICrossing = false; + + // + forceHasADXTrending = false; + forceHasADXCrossing = false; + // ZeroMemory(this); } @@ -447,11 +469,18 @@ bool DetectTriggerBlock1( // TODO: Remove this ... // filters.bosLoopback = 0; // filters.filterBasedOnPV = true; - // filters.filterBasedOnSar = false; + // filters.filterBasedOnSar = true; // filters.forceSarSwitched = false; // filters.forceSarOnBothSide = true; // filters.forceSarHasBreakout = true; // filters.forceSarHasReversalSide = false; + // filters.filterBasedOnRSI = false; + // filters.forceHasRSITrending = false; + // filters.forceHasRSIVPattern = false; + // filters.forceHasRSICrossing = false; + filters.filterBasedOnADX = true; + filters.forceHasADXTrending = false; + filters.forceHasADXCrossing = true; // // Apply Filtering ... @@ -1418,6 +1447,207 @@ bool FilterTriggerBlock( ? isSarBullishStart : isSarBearishStart; } + } + + // + // Filter Based On RSI ... + if (result && + filters.filterBasedOnRSI) + { + // + // Here We Can Apply RSI Filters ... + // Since RSI Filters must be Check on FVG Bars ... + // we Have to Loop back Based on FVG Bars to Detect Conditions ... + double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2; + + // + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex(); + + // + // Filter Using RSI Trending ... + if (result && + filters.forceHasRSITrending) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iRSI = helper.GetRSI(i); + double iPRSI = helper.GetRSI(i + 1); + + // + has = + (isBullish + ? (iRSI > rsiTrend && + iRSI > iPRSI) + : (iRSI < rsiTrend && + iRSI < iPRSI)); + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using RSI V Pattern ... + if (result && + filters.forceHasRSIVPattern) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iRSI = helper.GetRSI(i); + double iPRSI = helper.GetRSI(i + 1); + double iP2RSI = helper.GetRSI(i + 2); + + // + bool isRSIVBullish = + iRSI > iPRSI && + iP2RSI > iPRSI; + + // + bool isRSIVBearish = + iRSI < iPRSI && + iP2RSI < iPRSI; + + // + has = + (isBullish + ? isRSIVBullish + : isRSIVBearish); + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using RSI Crossing on OB/OS Levels ... + if (result && + filters.forceHasRSICrossing) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iRSI = helper.GetRSI(i); + double iPRSI = helper.GetRSI(i + 1); + + // + bool isRSICrossedOverOS = + iRSI > conditions.rsiOSLevel && + iPRSI <= conditions.rsiOSLevel; + + // + bool isRSICrossedUnderOB = + iRSI < conditions.rsiOBLevel && + iPRSI >= conditions.rsiOBLevel; + + // + has = + (isBullish + ? isRSICrossedOverOS + : isRSICrossedUnderOB); + if (has) + { + break; + } + } + + // + result = has; + } + } + + // + // Filter Based On ADX ... + if (result && + filters.filterBasedOnADX) + { + // + // Here We Can Apply ADX Filters ... + // Since ADX Filters must be Check on FVG Bars ... + // we Have to Loop back Based on FVG Bars to Detect Conditions ... + + // + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex(); + + // + // Filter Using ADX Trending ... + if (result && + filters.forceHasADXTrending) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iADX = helper.GetADX(i); + double iPADX = helper.GetADX(i + 1); + + // + has = iADX > conditions.adxThreshold && + iADX > iPADX; + if (has) + { + break; + } + } + + // + result = has; + } + + // + // Filter Using ADX Crossing on +DI/-DI ... + if (result && + filters.forceHasADXCrossing) + { + // + for (int i = toIDX; i < fromIDX; i++) + { + // + double iDIPlus = helper.GetADXP(i); + double iPDIPlus = helper.GetADXP(i + 1); + + // + double iDIMinus = helper.GetADXN(i); + double iPDIMinus = helper.GetADXN(i + 1); + + // + bool isADXPlusCrossedOverMinus = + iDIPlus > iDIMinus && + iPDIPlus <= iDIMinus; + + // + bool isADXMinusCrossedOverPlus = + iDIMinus > iDIPlus && + iPDIMinus <= iDIPlus; + + // + has = + isBullish + ? isADXPlusCrossedOverMinus + : isADXMinusCrossedOverPlus; + if (has) + { + break; + } + } + + // + result = has; + } // if (result)