diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 22f3154c..7fb77c38 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -4,32 +4,48 @@ "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2025-05-08T10:58:12.985Z", - "id": "7", + "creation_time": "2025-05-27T22:08:09.236Z", + "description": { + "content": "- Create a List of Guards;\n- implement Guards;\n", + "mime": "text/markdown" + }, + "id": "12", "references": [], - "title": "add support for Swings on Block Detection ..." + "title": "Complete Guards ..." }, { "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2025-05-08T10:50:29.074Z", - "id": "4", + "creation_time": "2025-05-27T22:08:57.604Z", + "description": { + "content": "- add Support for Multiple XTB Validations;\n- add a Counter to Positions Validation;\n- add Some Filter and Validation rules;\n", + "mime": "text/markdown" + }, + "id": "13", "references": [], - "title": "add support for OB in XCAEA POI Detector" - } - ], - "in-progress": [ + "title": "Edit XTriggerBlock Structure" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2025-05-09T15:08:11.261Z", - "id": "10", + "creation_time": "2025-05-27T22:07:32.052Z", + "id": "11", "references": [], - "title": "Add Support for Decision Box Finding Using Analyse ..." + "title": "Test Validations and Filters of XTriggerBlocks" + }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2025-05-27T22:10:00.132Z", + "id": "14", + "references": [], + "title": "add support for Save Trades" } ], + "in-progress": [], "testing": [ { "assignedTo": { @@ -82,6 +98,15 @@ "references": [], "title": "Add Support for Daily Max Volume and Ticks Box in XCAEA POI Detector ..." }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2025-05-09T15:08:11.261Z", + "id": "10", + "references": [], + "title": "Add Support for Decision Box Finding Using Analyse ..." + }, { "assignedTo": { "name": "Hadi Khazaee Asl" diff --git a/Documents/BKP/tmp-1.mql4 b/Documents/BKP/tmp-1.mql4 new file mode 100644 index 00000000..fc3bd654 --- /dev/null +++ b/Documents/BKP/tmp-1.mql4 @@ -0,0 +1,770 @@ + // hasTB && + // tb.IsBullish() && + // + // isPeakOverLast && + // isSarBullishStart + // && + // isTrendBullishStart && + // isADXBullishStart && + // && + // isSBarBullishStart + // && + // isHKSBarBullishStart + // + + + // + // hasTB && + // tb.IsBearish() && + // + // isValeUnderLast && + // isSarBearishStart + // && + // isTrendBearishStart && + // isADXBearishStart && + // && + // isSBarBearishStart + // && + // isHKSBarBearishStart + // + + + +bool DetectTriggerBlock( + XCPOIDrawer *drawer, + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + X121XCatbConditions &conditions, + XTriggerBlock &tb, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Normalize Args ... + tb.Clean(); + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = helper != NULL; + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + tb.Clean(); + conditions.Clean(); + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Checking Conditions ... + + // + // Detect Bar Verifications ... + + // + ENUM_X_DIRECTION iDir; + + // + // Rejected ... + bool isRejected = + barAnalyser + .IsRejected( + conditions.bars[cIDX], + iDir // + ); + bool isBullishRejected = + isRejected && + IsBullish(iDir); + bool isBearishRejected = + isRejected && + IsBearish(iDir); + + // + // Engulfed ... + bool isEngulfed = + barAnalyser + .IsEngulfed( + conditions.bars[cIDX], + iDir // + ); + bool isBullishEngulfed = + isEngulfed && + IsBullish(iDir); + bool isBearishEngulfed = + isEngulfed && + IsBearish(iDir); + + // + // Momentum ... + bool isMomentum = + barAnalyser + .IsMomentum( + conditions.bars[cIDX], + iDir // + ); + bool isBullishMomentum = + isMomentum && + IsBullish(iDir); + bool isBearishMomentum = + isMomentum && + IsBearish(iDir); + + // + bool isBarBullishPressured = + isBullishRejected || + isBullishEngulfed || + isBullishMomentum; + + // + bool isBarBearishPressured = + isBearishRejected || + isBearishEngulfed || + isBearishMomentum; + + // + // Detect Indicator Base Start Directional Movement ... + + // + // SAR ... + + // + bool isSarBullishStart = + // + ( + // + // Current SAR is Directional ... + conditions.isSarBullish && + // + // Previous InDirectional Sar Exists ... + helper.lastSarBearish.IsValid() && + // + // Current Close is Over previous Sar ... + conditions.bars[cIDX].close > helper.lastSarBearish.after && + // + // Before Close is not Over previous Sar ... + conditions.bars[pIDX].close <= helper.lastSarBearish.after + // + ) + // + ; + + // + bool isSarBearishStart = + // + ( + // + // Current SAR is Directional ... + conditions.isSarBearish && + // + // Previous InDirectional Sar Exists ... + helper.lastSarBullish.IsValid() && + // + // Current Close is Under previous ... + conditions.bars[cIDX].close < helper.lastSarBullish.after && + // + // Before Close is not Under previous ... + conditions.bars[pIDX].close >= helper.lastSarBullish.after + // + ) + // + ; + + // + // TREND ... + + // + bool isTrendBullishStart = + // + ( + // + // Current Trend is Directional ... + conditions.isTrendBullish && + // + // Previous InDirectiona; Trend Exists ... + helper.lastTrendBearish.IsValid() && + // + // Current Close is Over previous ... + conditions.bars[cIDX].close > helper.lastTrendBearish.after && + // + // Before close is not Over previous ... + conditions.bars[pIDX].close <= helper.lastTrendBearish.after + // + ) + // + ; + + // + bool isTrendBearishStart = + // + ( + // + // Current Trend is Directional ... + conditions.isTrendBearish && + // + // Previous InDirectiona; Trend Exists ... + helper.lastTrendBullish.IsValid() && + // + // Current Close is Under previous ... + conditions.bars[cIDX].close < helper.lastTrendBullish.after && + // + // Before close is not Under previous ... + conditions.bars[pIDX].close >= helper.lastTrendBullish.after + // + ) + // + ; + + // + // ADX ... + + // + bool isADXBullishStart = + // + ( + // + // ADX Value is Switched to Strong ... + conditions.adxBuffer[cIDX] > conditions.adxThreshold && + conditions.adxBuffer[pIDX] <= conditions.adxThreshold && + // + // ADX must Up ... + conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && + // + // ADX +DI is Bigger than -DI ... + conditions.adxpBuffer[cIDX] > conditions.adxnBuffer[cIDX] && + // + // ADX +DI is Up ... + conditions.adxpBuffer[cIDX] > conditions.adxpBuffer[pIDX] + // + ) + // + ; + + // + bool isADXBearishStart = + // + ( + // + // ADX Value is Switched to Strong ... + conditions.adxBuffer[cIDX] > conditions.adxThreshold && + conditions.adxBuffer[pIDX] <= conditions.adxThreshold && + // + // ADX must Up ... + conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && + // + // ADX -DI is Bigger than +DI ... + conditions.adxnBuffer[cIDX] > conditions.adxpBuffer[cIDX] && + // + // ADX -DI is Up ... + conditions.adxnBuffer[cIDX] > conditions.adxnBuffer[pIDX] + // + ) + // + ; + + // + // DELTA ... + + // + bool isDeltaBullishStart = + // + // Check State ... + ( + // + // Delta is Up ... + conditions.deltaBuffer[cIDX] > conditions.deltaBuffer[pIDX] && + // + // Delta Signal is Up ... + conditions.deltaSignalBuffer[cIDX] > conditions.deltaSignalBuffer[pIDX] && + // + // Delta Crossed Over Delta Signal ... + conditions.deltaBuffer[cIDX] > conditions.deltaSignalBuffer[cIDX] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastDeltaBearish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close > helper.lastDeltaBearish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close <= helper.lastDeltaBearish.after + // + ; + + // + bool isDeltaBearishStart = + // + // Check State ... + ( + // + // Delta is Down ... + conditions.deltaBuffer[cIDX] < conditions.deltaBuffer[pIDX] && + // + // Delta Signal is Down ... + conditions.deltaSignalBuffer[cIDX] < conditions.deltaSignalBuffer[pIDX] && + // + // Delta Crossed Under Delta Signal ... + conditions.deltaBuffer[cIDX] < conditions.deltaSignalBuffer[cIDX] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastDeltaBullish.IsValid() && + // + // Current Close is Under last ... + conditions.bars[cIDX].close < helper.lastDeltaBullish.after && + // + // Before Close is not Under last ... + conditions.bars[pIDX].close >= helper.lastDeltaBullish.after + // + ; + + // + // VOLUME ... + + // + bool isVolumeBullishStart = + // + ( + // + // + // Volume is Up ... + conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastVolumeBearish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close > helper.lastVolumeBearish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close <= helper.lastVolumeBearish.after + // + ; + + // + bool isVolumeBearishStart = + // + ( + // + // + // Volume is Up ... + conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastVolumeBullish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close < helper.lastVolumeBullish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close >= helper.lastVolumeBullish.after + // + ; + + // + // SIGNAL Bar ... + + // + bool isSBarBullishStart = + // + ( + // + // Check Direction ... + conditions.isSBarBullish && + // + // Previous InDirectional Exists ... + helper.lastSignalBarBearish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.sBarCloseBuffer[cIDX] > helper.lastSignalBarBearish.after && + // + // Prev Signal Bar not close over prev ... + conditions.sBarCloseBuffer[pIDX] <= helper.lastSignalBarBearish.after + // + ) + // + ; + + // + bool isSBarBearishStart = + // + ( + // + // Check Direction ... + conditions.isSBarBearish && + // + // Previous InDirectional Exists ... + helper.lastSignalBarBullish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.sBarCloseBuffer[cIDX] < helper.lastSignalBarBullish.after && + // + // Prev Signal Bar not close over prev ... + conditions.sBarCloseBuffer[pIDX] >= helper.lastSignalBarBullish.after + // + ) + // + ; + + // + // HKSIGNAL Bar ... + + // + bool isHKSBarBullishStart = + // + ( + // + // Check Direction ... + conditions.isHKSBarBullish && + // + // Previous InDirectional Exists ... + helper.lastHKSignalBarBearish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.hkSBarCloseBuffer[cIDX] > helper.lastHKSignalBarBearish.after && + // + // Prev Signal Bar not close over prev ... + conditions.hkSBarCloseBuffer[pIDX] <= helper.lastHKSignalBarBearish.after + // + ) + // + ; + + // + bool isHKSBarBearishStart = + // + ( + // + // Check Direction ... + conditions.isHKSBarBearish && + // + // Previous InDirectional Exists ... + helper.lastHKSignalBarBullish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.hkSBarCloseBuffer[cIDX] < helper.lastHKSignalBarBullish.after && + // + // Prev Signal Bar not close over prev ... + conditions.hkSBarCloseBuffer[pIDX] >= helper.lastHKSignalBarBullish.after + // + ) + // + ; + + // + // Check for Vale and Peak ... + + // + bool isPeakOverLast = + // + (conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] && + conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] && + conditions.bars[cIDX].close > conditions.peakBuffer[pIDX]) + // + || + // + (conditions.peakBuffer[pIDX] > conditions.peakBuffer[p2IDX] && + conditions.peakBuffer[p2IDX] <= conditions.peakBuffer[p3IDX] && + conditions.bars[pIDX].close > conditions.peakBuffer[p2IDX]) + // + || + // + (conditions.peakBuffer[p2IDX] > conditions.peakBuffer[p3IDX] && + conditions.peakBuffer[p3IDX] <= conditions.peakBuffer[p4IDX] && + conditions.bars[p2IDX].close > conditions.peakBuffer[p3IDX]) + // + ; + + // + bool isValeUnderLast = + // + (conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] && + conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] && + conditions.bars[cIDX].close < conditions.valeBuffer[pIDX]) + // + || + // + (conditions.valeBuffer[pIDX] < conditions.valeBuffer[p2IDX] && + conditions.valeBuffer[p2IDX] >= conditions.valeBuffer[p3IDX] && + conditions.bars[pIDX].close < conditions.valeBuffer[p2IDX]) + // + || + // + (conditions.valeBuffer[p2IDX] < conditions.valeBuffer[p3IDX] && + conditions.valeBuffer[p3IDX] >= conditions.valeBuffer[p4IDX] && + conditions.bars[p2IDX].close < conditions.valeBuffer[p3IDX]) + // + ; + + // + // if (isValeUnderLast) + // { + // Print("SALAM"); + // } + + // + // Try to Summarize Conditions ... + + // + bool isBullishPassed = + // + (isPeakOverLast && + isDeltaBullishStart && + isVolumeBullishStart && + isBarBullishPressured) + // + ; + + // + bool isBearishPassed = + (isValeUnderLast && + isDeltaBearishStart && + isVolumeBearishStart && + isBarBearishPressured) + // + ; + + // + // Try to Detect Trigger Block ... + bool hasTB = false; + int tbLoopback = 100; + X121XCatbInputs mInputs = helper.GetInputs(); + for (int i = barIndex; i < barIndex + tbLoopback; i++) + { + // + // Update Helper ... + helper.Update(i); + + // + // Check TB ... + hasTB = DetectTriggerBlock( + // + conditions.symbol, + conditions.period, + // + tb, + // + drawer, + barAnalyser, + // + // Required Buffers ... + helper.atrBuffer, + helper.rsiBuffer, + helper.adxBuffer, + helper.adxpBuffer, + helper.adxnBuffer, + helper.peakBuffer, + helper.valeBuffer, + helper.deltaBuffer, + helper.sarBuffer, + helper.sarStateBuffer, + helper.trendBuffer, + helper.trendStateBuffer, + helper.atrUpperBuffer, + helper.atrLowerBuffer, + helper.sBarOpenBuffer, + helper.sBarCloseBuffer, + helper.hkSBarOpenBuffer, + helper.hkSBarCloseBuffer, + helper.peakGoldenBuffer, + helper.valeGoldenBuffer, + helper.deltaSignalBuffer, + helper.bullishVolumeSignalBuffer, + helper.bearishVolumeSignalBuffer, + // + i + 1, + // + // Signalling ... + mInputs.signalR2R, + mInputs.slAtrMultiplier, + // + // Configs ... + mInputs.rsiOBLevel, + mInputs.rsiOSLevel, + mInputs.adxThreshold, + // + // Validators ... + mInputs.forceObBarType, + mInputs.forceOBFVGBarType, + mInputs.forceHasSwing, + mInputs.forceHasFLiquidity, + mInputs.forceHasRLiquidity, + mInputs.validateGapSequence, + mInputs.validateBlockEdgeBreakout, + // + // Filters ... + mInputs.filterBasedOnPV, + mInputs.filterBasedOnSar, + mInputs.filterBasedOnRSI, + mInputs.filterBasedOnADX, + mInputs.filterBasedOnATR, + mInputs.filterBasedOnTrend, + mInputs.filterBasedOnDelta, + mInputs.filterBasedOnVolume, + mInputs.filterBasedOnSignalBar, + mInputs.filterBasedOnHKSignalBar // + ); + + // + // Checking Trigger Block Validation ... + hasTB = + // + hasTB && + // + ( + // + (isBullishPassed && + tb.IsBullish()) + // + || + // + (isBearishPassed && + tb.IsBearish()) + // + ); + if (hasTB) + { + // + break; + } + + // + tb.Clean(); + } + + // + // isBullishPassed = false; + // isBearishPassed = false; + + // + // Draw Line for Detect Conditions States on Chart ... + if (hasTB && (isBullishPassed || + isBearishPassed)) + { + // + color iColor = isBullishPassed + ? clrAqua + : clrMagenta; + + // + datetime iTime = conditions.bars[cIDX].time; + + // + string iName = "VL_" + ToFormatString(iTime); + + // + long chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + CChartObjectVLine *iObj; + iObj = new CChartObjectVLine(); + bool isDrawn = iObj.Create( + chartID, + iName, + subWindow, + iTime // + ); + if (isDrawn) + { + // + iObj.Color(iColor); + } + + // + CArrayObj *tbObjects = new CArrayObj(); + DrawTriggerBlock( + tb, + drawer, + tbObjects, + conditions.bars[0].time // + ); + + // + tb.Clean(); + } + + // + // Summarizing result ... + + // + result = (isBullishPassed || + isBearishPassed); + + // + // Cleanup Resources ... + + // + if (!result) + { + // + tb.Clean(); + conditions.Clean(); + } + + // + return result; +} + + + // + // has = DetectTriggerBlock( + // eaDrawer, + // eaHelper, + // eaBarAnalyser, + // iConditions, + // iTB, + // barIndex, + // 10 // + // ); diff --git a/Experts/xcatb.test.ea.mq5 b/Experts/xcatb.test.ea.mq5 index ff84c224..f488a06d 100644 --- a/Experts/xcatb.test.ea.mq5 +++ b/Experts/xcatb.test.ea.mq5 @@ -51,7 +51,7 @@ input group "Detector"; // Validating ... input group "Validations"; input bool eaForceHasSwing = false; // Force Blocks to Have Swing -input bool eaForceObBarType = false; // Force Block Has Reversal Bar +input bool eaForceOBBarType = false; // Force Block Has Reversal Bar input bool eaForceOBFVGBarType = false; // Force FVG Has Same Bars input bool eaForceHasFLiquidity = false; // Force Blocks to Have Following Liquidity input bool eaForceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity @@ -75,8 +75,8 @@ input bool eaFilterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Sig // // Signal ... input group "Signal"; -input int eaSignalR2R = 3; // Risk Reward Ratio -input double eaSLAtrMultiplier = 0.5; // ATR Multiplier for SL +input int eaSignalR2R = 2; // Risk Reward Ratio +input double eaSLAtrMultiplier = 0; // ATR Multiplier for SL // // Volume ... @@ -97,10 +97,10 @@ input bool eaAllowTrade = true; input bool eaAllowLongs = true; // Allow Long Trades input bool eaAllowShorts = true; // Allow Short Trades input string eaSessions = ""; // Active Sessions -input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Trade Restrictions Period -input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) per Day -input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) per Day -input int eaMaxAllowedTrades = 0; // Max Allowed Trades per Day +input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Restrictions Period +input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) in Restrictions Period +input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) in Restrictions Period +input int eaMaxAllowedTrades = 0; // Max Allowed Trades in Restrictions Period input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade @@ -300,94 +300,168 @@ void OnTick() if (tradeUsingTriggerBlock) { // - XTriggerBlock iTB; - X121XCatbConditions iConditions; - has = DetectTriggerBlock( - // - _Symbol, - _Period, - // - iTB, - // - eaDrawer, - eaBarAnalyser, - // - // Required Buffers ... - eaHelper.atrBuffer, - eaHelper.rsiBuffer, - eaHelper.adxBuffer, - eaHelper.adxpBuffer, - eaHelper.adxnBuffer, - eaHelper.peakBuffer, - eaHelper.valeBuffer, - eaHelper.deltaBuffer, - eaHelper.sarBuffer, - eaHelper.sarStateBuffer, - eaHelper.trendBuffer, - eaHelper.trendStateBuffer, - eaHelper.atrUpperBuffer, - eaHelper.atrLowerBuffer, - eaHelper.sBarOpenBuffer, - eaHelper.sBarCloseBuffer, - eaHelper.hkSBarOpenBuffer, - eaHelper.hkSBarCloseBuffer, - eaHelper.peakGoldenBuffer, - eaHelper.valeGoldenBuffer, - eaHelper.deltaSignalBuffer, - eaHelper.bullishVolumeSignalBuffer, - eaHelper.bearishVolumeSignalBuffer, - // - cBarIndex, - // - // Signalling ... - eaInputs.signalR2R, - eaInputs.slAtrMultiplier, - // - // Configs ... - eaInputs.rsiOBLevel, - eaInputs.rsiOSLevel, - eaInputs.adxThreshold, - // - // Validators ... - eaInputs.forceObBarType, - eaInputs.forceOBFVGBarType, - eaInputs.forceHasSwing, - eaInputs.forceHasFLiquidity, - eaInputs.forceHasRLiquidity, - eaInputs.validateGapSequence, - eaInputs.validateBlockEdgeBreakout, - // - // Filters ... - eaInputs.filterBasedOnPV, - eaInputs.filterBasedOnSar, - eaInputs.filterBasedOnRSI, - eaInputs.filterBasedOnADX, - eaInputs.filterBasedOnATR, - eaInputs.filterBasedOnTrend, - eaInputs.filterBasedOnDelta, - eaInputs.filterBasedOnVolume, - eaInputs.filterBasedOnSignalBar, - eaInputs.filterBasedOnHKSignalBar // - ); + // XTriggerBlock iTB; + // X121XCatbConditions iConditions; + // has = DetectTriggerBlock( + // // + // _Symbol, + // _Period, + // // + // iTB, + // // + // eaDrawer, + // eaBarAnalyser, + // // + // // Required Buffers ... + // eaHelper.atrBuffer, + // eaHelper.rsiBuffer, + // eaHelper.adxBuffer, + // eaHelper.adxpBuffer, + // eaHelper.adxnBuffer, + // eaHelper.peakBuffer, + // eaHelper.valeBuffer, + // eaHelper.deltaBuffer, + // eaHelper.sarBuffer, + // eaHelper.sarStateBuffer, + // eaHelper.trendBuffer, + // eaHelper.trendStateBuffer, + // eaHelper.atrUpperBuffer, + // eaHelper.atrLowerBuffer, + // eaHelper.sBarOpenBuffer, + // eaHelper.sBarCloseBuffer, + // eaHelper.hkSBarOpenBuffer, + // eaHelper.hkSBarCloseBuffer, + // eaHelper.peakGoldenBuffer, + // eaHelper.valeGoldenBuffer, + // eaHelper.deltaSignalBuffer, + // eaHelper.bullishVolumeSignalBuffer, + // eaHelper.bearishVolumeSignalBuffer, + // // + // cBarIndex, + // // + // // Signalling ... + // eaInputs.signalR2R, + // eaInputs.slAtrMultiplier, + // // + // // Configs ... + // eaInputs.rsiOBLevel, + // eaInputs.rsiOSLevel, + // eaInputs.adxThreshold, + // // + // // Validators ... + // eaInputs.forceObBarType, + // eaInputs.forceOBFVGBarType, + // eaInputs.forceHasSwing, + // eaInputs.forceHasFLiquidity, + // eaInputs.forceHasRLiquidity, + // eaInputs.validateGapSequence, + // eaInputs.validateBlockEdgeBreakout, + // // + // // Filters ... + // eaInputs.filterBasedOnPV, + // eaInputs.filterBasedOnSar, + // eaInputs.filterBasedOnRSI, + // eaInputs.filterBasedOnADX, + // eaInputs.filterBasedOnATR, + // eaInputs.filterBasedOnTrend, + // eaInputs.filterBasedOnDelta, + // eaInputs.filterBasedOnVolume, + // eaInputs.filterBasedOnSignalBar, + // eaInputs.filterBasedOnHKSignalBar // + // ); // - // has = DetectTriggerBlock( - // eaDrawer, - // eaHelper, - // eaBarAnalyser, - // iConditions, - // iTB, - // barIndex, - // 10 // - // ); + // Define Requirements ... + XTriggerBlock iTB; + XTriggerBlockFilters iFilters; + X121XCatbConditions iConditions; + XTriggerBlockValidationRules iValidations; + + // + // Fill Validations ... + iValidations.forceHasSwing = eaInputs.forceHasSwing; + iValidations.forceOBBarType = eaInputs.forceOBBarType; + iValidations.forceFVGBarType = eaInputs.forceOBFVGBarType; + iValidations.forceHasFLiquidity = eaInputs.forceHasFLiquidity; + iValidations.forceHasRLiquidity = eaInputs.forceHasRLiquidity; + iValidations.validateGapSequence = eaInputs.validateGapSequence; + iValidations.validateBlockEdgeBreakout = eaInputs.validateBlockEdgeBreakout; + + // + // Fill Filters ... + iFilters.filterBasedOnPV = eaInputs.filterBasedOnPV; + iFilters.filterBasedOnSar = eaInputs.filterBasedOnSar; + iFilters.filterBasedOnRSI = eaInputs.filterBasedOnRSI; + iFilters.filterBasedOnADX = eaInputs.filterBasedOnADX; + iFilters.filterBasedOnATR = eaInputs.filterBasedOnATR; + iFilters.filterBasedOnTrend = eaInputs.filterBasedOnTrend; + iFilters.filterBasedOnDelta = eaInputs.filterBasedOnDelta; + iFilters.filterBasedOnVolume = eaInputs.filterBasedOnVolume; + iFilters.filterBasedOnSignalBar = eaInputs.filterBasedOnSignalBar; + iFilters.filterBasedOnHKSignalBar = eaInputs.filterBasedOnHKSignalBar; + + // + // Trigger Block Detection ... + has = DetectTriggerBlock1( + eaHelper, + eaBarAnalyser, + iTB, + iConditions, + iValidations, + iFilters, + barIndex, + 10 // Loopback ... + ); // if (has) { // + // Wait for Next Bar for anything ... eaBarTraker.Waits(); // + // Prepare Target ... + double targets[]; + for (int i = 1; i <= eaInputs.signalR2R; i++) + { + // + Add( + (double)i, + targets // + ); + } + + // + // Calculate SL Additions ... + double iATR = 0; + if (barIndex > 0 && + barIndex < ArraySize(eaHelper.atrBuffer)) + { + iATR = eaHelper.atrBuffer[barIndex]; + } + double slAdditional = eaInputs.slAtrMultiplier * iATR; + + // + // Preparing Signal ... + has = ToSignal( + iTB.trigger, + iTB.signal, + targets, + slAdditional // + ); + + // + // Draw Trigger Block ... + DrawTriggerBlock( + iTB, + eaDrawer, + eaObjects, + NULL // + ); + + // + // Attach Signal ... eaSignal = iTB.signal; // @@ -436,7 +510,7 @@ void OnTick() // XBoxZone signalZone; X121XCatbConditions conditions; - has = DetectSignalZone1( + has = DetectSignalZone( eaDrawer, eaHelper, eaBarAnalyser, @@ -739,7 +813,7 @@ void InitRequirements() // // Set Validators ... eaInputs.forceHasSwing = eaForceHasSwing; - eaInputs.forceObBarType = eaForceObBarType; + eaInputs.forceOBBarType = eaForceOBBarType; eaInputs.forceOBFVGBarType = eaForceOBFVGBarType; eaInputs.forceHasFLiquidity = eaForceHasFLiquidity; eaInputs.forceHasRLiquidity = eaForceHasRLiquidity; diff --git a/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Helpers/x-saherelm.x121.xcatb.helper.mq5 index d1c6796b..fb3752fe 100644 --- a/Helpers/x-saherelm.x121.xcatb.helper.mq5 +++ b/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -105,7 +105,7 @@ struct X121XCatbInputs // // Validating ... bool forceHasSwing; // Force Blocks to Have Swing - bool forceObBarType; // Force Block Has Reversal Bar + bool forceOBBarType; // Force Block Has Reversal Bar bool forceOBFVGBarType; // Force FVG Has Same Bars bool forceHasFLiquidity; // Force Blocks to Have Following Liquidity bool forceHasRLiquidity; // Force Blocks to Have Reversal Liquidity @@ -188,7 +188,7 @@ struct X121XCatbInputs // // Validating ... forceHasSwing = false; // Force Blocks to Have Swing - forceObBarType = false; // Force Block Has Reversal Bar + forceOBBarType = false; // Force Block Has Reversal Bar forceOBFVGBarType = false; // Force FVG Has Same Bars forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity @@ -265,7 +265,7 @@ struct X121XCatbInputs // // Validating ... forceHasSwing = false; // Force Blocks to Have Swing - forceObBarType = false; // Force Block Has Reversal Bar + forceOBBarType = false; // Force Block Has Reversal Bar forceOBFVGBarType = false; // Force FVG Has Same Bars forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity @@ -1588,7 +1588,7 @@ class XCX121XCatbHelper : public XCBaseHelper mInputs.slAtrMultiplier, "", // Validating ... mInputs.forceHasSwing, - mInputs.forceObBarType, + mInputs.forceOBBarType, mInputs.forceOBFVGBarType, mInputs.forceHasFLiquidity, mInputs.forceHasRLiquidity, @@ -4401,9 +4401,9 @@ class XCX121XCatbHelper : public XCBaseHelper // Calculate ... // - double rsiOBLevel = mInputs.rsiOBLevel; // Over Bought Level - double rsiOSLevel = mInputs.rsiOSLevel; // Over Sold Level - double adxThreshold = mInputs.adxThreshold; // Big Movement Threshold + double _rsiOBLevel = mInputs.rsiOBLevel; // Over Bought Level + double _rsiOSLevel = mInputs.rsiOSLevel; // Over Sold Level + double _adxThreshold = mInputs.adxThreshold; // Big Movement Threshold // // Reading Values ... @@ -4646,15 +4646,15 @@ class XCX121XCatbHelper : public XCBaseHelper // bool isADXOverThreshold = - cADX > adxThreshold; + cADX > _adxThreshold; bool isADXUnderThreshold = - cADX < adxThreshold; + cADX < _adxThreshold; // bool isPADXOverThreshold = - pADX > adxThreshold; + pADX > _adxThreshold; bool isPADXUnderThreshold = - pADX < adxThreshold; + pADX < _adxThreshold; // bool isDXPBiggerThanDXN = @@ -4711,25 +4711,25 @@ class XCX121XCatbHelper : public XCBaseHelper // bool isRSIOB = - cRSI > rsiOBLevel; + cRSI > _rsiOBLevel; bool isRSIOS = - cRSI < rsiOSLevel; + cRSI < _rsiOSLevel; // bool isRSICrossedOverOB = - cRSI > rsiOBLevel && - pRSI <= rsiOBLevel; + cRSI > _rsiOBLevel && + pRSI <= _rsiOBLevel; bool isRSICrossedOverOS = - cRSI > rsiOSLevel && - pRSI <= rsiOSLevel; + cRSI > _rsiOSLevel && + pRSI <= _rsiOSLevel; // bool isRSICrossedUnderOB = - cRSI < rsiOBLevel && - pRSI >= rsiOBLevel; + cRSI < _rsiOBLevel && + pRSI >= _rsiOBLevel; bool isRSICrossedUnderOS = - cRSI < rsiOSLevel && - pRSI >= rsiOSLevel; + cRSI < _rsiOSLevel && + pRSI >= _rsiOSLevel; // // DELTA ... @@ -4886,11 +4886,11 @@ class XCX121XCatbHelper : public XCBaseHelper conditions.isDeltaUp = isDeltaUp; conditions.isATRDown = isATRDown; conditions.isTrendUp = isTrendUp; - conditions.rsiOBLevel = rsiOBLevel; - conditions.rsiOSLevel = rsiOSLevel; + conditions.rsiOBLevel = _rsiOBLevel; + conditions.rsiOSLevel = _rsiOSLevel; conditions.isDeltaDown = isDeltaDown; conditions.isTrendDown = isTrendDown; - conditions.adxThreshold = adxThreshold; + conditions.adxThreshold = _adxThreshold; conditions.isSarBullish = isSarBullish; conditions.isSarBearish = isSarBearish; conditions.isADXBullish = isADXBullish; diff --git a/Libraries/x-saherelm.x121.xcatb.lib.mq5 b/Libraries/x-saherelm.x121.xcatb.lib.mq5 index a23fa9b3..21b49c43 100644 --- a/Libraries/x-saherelm.x121.xcatb.lib.mq5 +++ b/Libraries/x-saherelm.x121.xcatb.lib.mq5 @@ -30,6 +30,10 @@ // // Definiions ... +// +#define XLiquidityToken "XLQ"; +#define XTriggerBlockToken "XTRG"; + // struct XTriggerBlock { @@ -133,11 +137,449 @@ struct XTriggerBlock // }; +// +// Trigger Block Validation Rules ... +struct XTriggerBlockValidationRules +{ + // + // Props ... + bool forceHasSwing; // Force Block to Has Propper Swing ... + bool forceOBBarType; // Force Order Block to Has InDirectional Bars ... + bool forceFVGBarType; // Force Fair Value Gaps Bars Type ... + double maxAllowedRange; // Max Allowed Order Block Range ... + bool forceHasFLiquidity; // Force Order Block To Has Reversal Liquidity ... + bool forceHasRLiquidity; // Force Order Block to Has Following Liquidity ... + bool validateGapSequence; // Validate Fair Value Gaps Bar Sequences ... + bool validateBlockEdgeBreakout; // Validate Order Block Edge Breakeout ... + + // + // Constructor(s) ... + XTriggerBlockValidationRules() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + maxAllowedRange = 0; + forceHasSwing = false; + forceOBBarType = false; + forceFVGBarType = false; + forceHasFLiquidity = false; + forceHasRLiquidity = false; + validateGapSequence = false; + validateBlockEdgeBreakout = false; + + // + ZeroMemory(this); + } +}; + +// +// Trigger Block Filters ... +struct XTriggerBlockFilters +{ + // + // Props ... + bool filterBasedOnPV; // Filter Based On PV ... + bool filterBasedOnSar; // Filter Based On SAR ... + bool filterBasedOnRSI; // Filter Based On RSI ... + bool filterBasedOnADX; // Filter Based On ADX ... + bool filterBasedOnATR; // Filter Based On ATR ... + bool filterBasedOnTrend; // Filter Based On Trend ... + bool filterBasedOnDelta; // Filter Based On Delta ... + bool filterBasedOnVolume; // Filter Based On Volume ... + bool filterBasedOnSignalBar; // Filter Based on Signal Bar ... + bool filterBasedOnHKSignalBar; // Filter Based On HK Signal Bar ... + + // + // Constructor(s) ... + XTriggerBlockFilters() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + filterBasedOnPV = false; + filterBasedOnSar = false; + filterBasedOnRSI = false; + filterBasedOnADX = false; + filterBasedOnATR = false; + filterBasedOnTrend = false; + filterBasedOnDelta = false; + filterBasedOnVolume = false; + filterBasedOnSignalBar = false; + filterBasedOnHKSignalBar = false; + + // + ZeroMemory(this); + } +}; + // // Extensions ... // -bool DetectSignalZone1( +bool DetectTriggerBlock1( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations, + XTriggerBlockFilters &filters, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Normalize Args ... + conditions.Clean(); + triggerBlock.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL; + if (!result) + { + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + bool has = false; + string symbol = helper.GetSymbol(); + ENUM_TIMEFRAMES period = helper.GetPeriod(); + + // + // Initial Requirements ... + + // + // Required Bars ... + XOHCL zBar; + XOHCL cBar; + result = + result && + zBar.Init( + symbol, + period, + barIndex // + ); + result = + result && + zBar.GetPreviousBar(cBar); + + // + // Here we Must Detect Order Block ... + // then Detect FVG ... + // then Prepare Trigger Box ... + + // + // Select Application Bar ... + XOHCL iBar; + if (barIndex == 0) + { + iBar = cBar; + } + else if (barIndex > 0) + { + iBar = zBar; + } + iBar = cBar; + result = + result && + iBar.IsValid(); + + // + // Detect Order Block ... + result = + result && + barAnalyser + .IsOB( + iBar, + triggerBlock.ob, + false, + false // + ); + + // + // Detect Fair Value Gap ... + result = + result && + barAnalyser + .IsFVG( + iBar, + triggerBlock.fvg, + false // + ); + + // + // Check Result and Create Trigger Box based on it ... + if (result) + { + // + triggerBlock.trigger = triggerBlock.ob; + triggerBlock.trigger.type = XTriggerBlockToken; + } + + // + // Apply Validations ... + if (result) + { + // + result = ValidateTriggerBlock( + helper, + barAnalyser, + triggerBlock, + conditions, + validations, + barIndex, + loopback // + ); + + // + if (!result) + { + triggerBlock.Clean(); + } + } + + // + // Apply Filtering ... + if (result) + { + // + result = FilterTriggerBlock( + helper, + barAnalyser, + triggerBlock, + conditions, + filters, + barIndex, + loopback // + ); + + // + if (!result) + { + triggerBlock.Clean(); + } + } + + // + // Summarizing Result ... + result = + result && + triggerBlock.IsValid(); + + // + // Preparing Signal ... + if (result) { + // + + } + + // + // Cleanup Resources ... + + // + zBar.Clean(); + cBar.Clean(); + + // + if (!result) + { + triggerBlock.Clean(); + } + + // + return result; +} + +// +bool ValidateTriggerBlock( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Checking Conditions ... + + // + // Normalize Args ... + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid(); + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Checking Conditions ... + + // + // Summarize result ... + result = triggerBlock.IsValid(); + + // + // Cleanup Resources ... + + // + if (!result) + { + conditions.Clean(); + } + + // + return result; +} + +// +bool FilterTriggerBlock( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockFilters &filters, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Checking Conditions ... + + // + // Normalize Args ... + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid(); + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Checking Conditions ... + + // + // Summarize result ... + result = triggerBlock.IsValid(); + + // + // Cleanup Resources ... + + // + if (!result) + { + conditions.Clean(); + } + + // + return result; +} + +// +bool DetectSignalZone( XCPOIDrawer *&drawer, XCX121XCatbHelper *helper, XCBarAnalyser *barAnalyser, @@ -181,6 +623,9 @@ bool DetectSignalZone1( // signalZone.Clean(); conditions.Clean(); + + // + return result; } // @@ -191,6 +636,15 @@ bool DetectSignalZone1( int p3IDX = p2IDX + 1; int p4IDX = p3IDX + 1; + // + double sl = 0; + double tp = 0; + double upper = 0; + double lower = 0; + datetime to = NULL; + datetime from = NULL; + string signalProvider = NULL; + // // Checking Conditions ... @@ -653,18 +1107,38 @@ bool DetectSignalZone1( // Bearish ... bool isCond1Bearish = false; + // + bool isCond1 = + isCond1Bullish || + isCond1Bearish; + if (isCond1) + { + // + // Prepare Cond1 Based Requirements ... + + // + to = NULL; + upper = 0; + lower = 0; + from = NULL; + + // + // Provider Definition ... + signalProvider = "Cond1"; + } + // // Try to Summarize Conditions ... // - bool isBullishPassed = + bool isBullish = // isCond1Bullish // ; // - bool isBearishPassed = + bool isBearish = // isCond1Bearish // @@ -673,725 +1147,33 @@ bool DetectSignalZone1( // // Summarize Result ... result = - isBullishPassed || - isBearishPassed; - - // - return result; -} - -bool DetectTriggerBlock( - XCPOIDrawer *drawer, - XCX121XCatbHelper *helper, - XCBarAnalyser *barAnalyser, - X121XCatbConditions &conditions, - XTriggerBlock &tb, - int barIndex = 0, - int loopback = 10 // -) -{ - // - bool result = false; - - // - // Normalize Args ... - tb.Clean(); - conditions.Clean(); - barIndex = NormalizeInt(barIndex, 0); - loopback = NormalizeInt(loopback, 0); - - // - // Validate Args ... - result = helper != NULL; - if (!result) - { - return result; - } - - // - // Reading Market Conditions ... - result = helper.GetConditions( - conditions, - barIndex, - loopback // - ); - if (!result) + isBullish || + isBearish; + if (result) { // - tb.Clean(); - conditions.Clean(); + // Prepare Signal Zone ... + + // + signalZone.to = to; + signalZone.from = from; + signalZone.upper = upper; + signalZone.lower = lower; + signalZone.type = signalProvider; + signalZone.symbol = conditions.symbol; + signalZone.period = conditions.period; + + // + signalZone.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Validate Signal Zone ... + result = signalZone.IsValid(); } - // - int zIDX = 0; - int cIDX = zIDX + 1; - int pIDX = cIDX + 1; - int p2IDX = pIDX + 1; - int p3IDX = p2IDX + 1; - int p4IDX = p3IDX + 1; - - // - // Checking Conditions ... - - // - // Detect Bar Verifications ... - - // - ENUM_X_DIRECTION iDir; - - // - // Rejected ... - bool isRejected = - barAnalyser - .IsRejected( - conditions.bars[cIDX], - iDir // - ); - bool isBullishRejected = - isRejected && - IsBullish(iDir); - bool isBearishRejected = - isRejected && - IsBearish(iDir); - - // - // Engulfed ... - bool isEngulfed = - barAnalyser - .IsEngulfed( - conditions.bars[cIDX], - iDir // - ); - bool isBullishEngulfed = - isEngulfed && - IsBullish(iDir); - bool isBearishEngulfed = - isEngulfed && - IsBearish(iDir); - - // - // Momentum ... - bool isMomentum = - barAnalyser - .IsMomentum( - conditions.bars[cIDX], - iDir // - ); - bool isBullishMomentum = - isMomentum && - IsBullish(iDir); - bool isBearishMomentum = - isMomentum && - IsBearish(iDir); - - // - bool isBarBullishPressured = - isBullishRejected || - isBullishEngulfed || - isBullishMomentum; - - // - bool isBarBearishPressured = - isBearishRejected || - isBearishEngulfed || - isBearishMomentum; - - // - // Detect Indicator Base Start Directional Movement ... - - // - // SAR ... - - // - bool isSarBullishStart = - // - ( - // - // Current SAR is Directional ... - conditions.isSarBullish && - // - // Previous InDirectional Sar Exists ... - helper.lastSarBearish.IsValid() && - // - // Current Close is Over previous Sar ... - conditions.bars[cIDX].close > helper.lastSarBearish.after && - // - // Before Close is not Over previous Sar ... - conditions.bars[pIDX].close <= helper.lastSarBearish.after - // - ) - // - ; - - // - bool isSarBearishStart = - // - ( - // - // Current SAR is Directional ... - conditions.isSarBearish && - // - // Previous InDirectional Sar Exists ... - helper.lastSarBullish.IsValid() && - // - // Current Close is Under previous ... - conditions.bars[cIDX].close < helper.lastSarBullish.after && - // - // Before Close is not Under previous ... - conditions.bars[pIDX].close >= helper.lastSarBullish.after - // - ) - // - ; - - // - // TREND ... - - // - bool isTrendBullishStart = - // - ( - // - // Current Trend is Directional ... - conditions.isTrendBullish && - // - // Previous InDirectiona; Trend Exists ... - helper.lastTrendBearish.IsValid() && - // - // Current Close is Over previous ... - conditions.bars[cIDX].close > helper.lastTrendBearish.after && - // - // Before close is not Over previous ... - conditions.bars[pIDX].close <= helper.lastTrendBearish.after - // - ) - // - ; - - // - bool isTrendBearishStart = - // - ( - // - // Current Trend is Directional ... - conditions.isTrendBearish && - // - // Previous InDirectiona; Trend Exists ... - helper.lastTrendBullish.IsValid() && - // - // Current Close is Under previous ... - conditions.bars[cIDX].close < helper.lastTrendBullish.after && - // - // Before close is not Under previous ... - conditions.bars[pIDX].close >= helper.lastTrendBullish.after - // - ) - // - ; - - // - // ADX ... - - // - bool isADXBullishStart = - // - ( - // - // ADX Value is Switched to Strong ... - conditions.adxBuffer[cIDX] > conditions.adxThreshold && - conditions.adxBuffer[pIDX] <= conditions.adxThreshold && - // - // ADX must Up ... - conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && - // - // ADX +DI is Bigger than -DI ... - conditions.adxpBuffer[cIDX] > conditions.adxnBuffer[cIDX] && - // - // ADX +DI is Up ... - conditions.adxpBuffer[cIDX] > conditions.adxpBuffer[pIDX] - // - ) - // - ; - - // - bool isADXBearishStart = - // - ( - // - // ADX Value is Switched to Strong ... - conditions.adxBuffer[cIDX] > conditions.adxThreshold && - conditions.adxBuffer[pIDX] <= conditions.adxThreshold && - // - // ADX must Up ... - conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && - // - // ADX -DI is Bigger than +DI ... - conditions.adxnBuffer[cIDX] > conditions.adxpBuffer[cIDX] && - // - // ADX -DI is Up ... - conditions.adxnBuffer[cIDX] > conditions.adxnBuffer[pIDX] - // - ) - // - ; - - // - // DELTA ... - - // - bool isDeltaBullishStart = - // - // Check State ... - ( - // - // Delta is Up ... - conditions.deltaBuffer[cIDX] > conditions.deltaBuffer[pIDX] && - // - // Delta Signal is Up ... - conditions.deltaSignalBuffer[cIDX] > conditions.deltaSignalBuffer[pIDX] && - // - // Delta Crossed Over Delta Signal ... - conditions.deltaBuffer[cIDX] > conditions.deltaSignalBuffer[cIDX] - // - ) - // - && - // - // Check Last InDirectional Exists ... - helper.lastDeltaBearish.IsValid() && - // - // Current Close is Over last ... - conditions.bars[cIDX].close > helper.lastDeltaBearish.after && - // - // Before Close is not Over last ... - conditions.bars[pIDX].close <= helper.lastDeltaBearish.after - // - ; - - // - bool isDeltaBearishStart = - // - // Check State ... - ( - // - // Delta is Down ... - conditions.deltaBuffer[cIDX] < conditions.deltaBuffer[pIDX] && - // - // Delta Signal is Down ... - conditions.deltaSignalBuffer[cIDX] < conditions.deltaSignalBuffer[pIDX] && - // - // Delta Crossed Under Delta Signal ... - conditions.deltaBuffer[cIDX] < conditions.deltaSignalBuffer[cIDX] - // - ) - // - && - // - // Check Last InDirectional Exists ... - helper.lastDeltaBullish.IsValid() && - // - // Current Close is Under last ... - conditions.bars[cIDX].close < helper.lastDeltaBullish.after && - // - // Before Close is not Under last ... - conditions.bars[pIDX].close >= helper.lastDeltaBullish.after - // - ; - - // - // VOLUME ... - - // - bool isVolumeBullishStart = - // - ( - // - // - // Volume is Up ... - conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] && - // - // Volume Signal is Up ... - conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] && - // - // Volume Signals Crossed Over ... - conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1] - // - ) - // - && - // - // Check Last InDirectional Exists ... - helper.lastVolumeBearish.IsValid() && - // - // Current Close is Over last ... - conditions.bars[cIDX].close > helper.lastVolumeBearish.after && - // - // Before Close is not Over last ... - conditions.bars[pIDX].close <= helper.lastVolumeBearish.after - // - ; - - // - bool isVolumeBearishStart = - // - ( - // - // - // Volume is Up ... - conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] && - // - // Volume Signal is Up ... - conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] && - // - // Volume Signals Crossed Over ... - conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1] - // - ) - // - && - // - // Check Last InDirectional Exists ... - helper.lastVolumeBullish.IsValid() && - // - // Current Close is Over last ... - conditions.bars[cIDX].close < helper.lastVolumeBullish.after && - // - // Before Close is not Over last ... - conditions.bars[pIDX].close >= helper.lastVolumeBullish.after - // - ; - - // - // SIGNAL Bar ... - - // - bool isSBarBullishStart = - // - ( - // - // Check Direction ... - conditions.isSBarBullish && - // - // Previous InDirectional Exists ... - helper.lastSignalBarBearish.IsValid() && - // - // Current Signal Bar close over prev ... - conditions.sBarCloseBuffer[cIDX] > helper.lastSignalBarBearish.after && - // - // Prev Signal Bar not close over prev ... - conditions.sBarCloseBuffer[pIDX] <= helper.lastSignalBarBearish.after - // - ) - // - ; - - // - bool isSBarBearishStart = - // - ( - // - // Check Direction ... - conditions.isSBarBearish && - // - // Previous InDirectional Exists ... - helper.lastSignalBarBullish.IsValid() && - // - // Current Signal Bar close over prev ... - conditions.sBarCloseBuffer[cIDX] < helper.lastSignalBarBullish.after && - // - // Prev Signal Bar not close over prev ... - conditions.sBarCloseBuffer[pIDX] >= helper.lastSignalBarBullish.after - // - ) - // - ; - - // - // HKSIGNAL Bar ... - - // - bool isHKSBarBullishStart = - // - ( - // - // Check Direction ... - conditions.isHKSBarBullish && - // - // Previous InDirectional Exists ... - helper.lastHKSignalBarBearish.IsValid() && - // - // Current Signal Bar close over prev ... - conditions.hkSBarCloseBuffer[cIDX] > helper.lastHKSignalBarBearish.after && - // - // Prev Signal Bar not close over prev ... - conditions.hkSBarCloseBuffer[pIDX] <= helper.lastHKSignalBarBearish.after - // - ) - // - ; - - // - bool isHKSBarBearishStart = - // - ( - // - // Check Direction ... - conditions.isHKSBarBearish && - // - // Previous InDirectional Exists ... - helper.lastHKSignalBarBullish.IsValid() && - // - // Current Signal Bar close over prev ... - conditions.hkSBarCloseBuffer[cIDX] < helper.lastHKSignalBarBullish.after && - // - // Prev Signal Bar not close over prev ... - conditions.hkSBarCloseBuffer[pIDX] >= helper.lastHKSignalBarBullish.after - // - ) - // - ; - - // - // Check for Vale and Peak ... - - // - bool isPeakOverLast = - // - (conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] && - conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] && - conditions.bars[cIDX].close > conditions.peakBuffer[pIDX]) - // - || - // - (conditions.peakBuffer[pIDX] > conditions.peakBuffer[p2IDX] && - conditions.peakBuffer[p2IDX] <= conditions.peakBuffer[p3IDX] && - conditions.bars[pIDX].close > conditions.peakBuffer[p2IDX]) - // - || - // - (conditions.peakBuffer[p2IDX] > conditions.peakBuffer[p3IDX] && - conditions.peakBuffer[p3IDX] <= conditions.peakBuffer[p4IDX] && - conditions.bars[p2IDX].close > conditions.peakBuffer[p3IDX]) - // - ; - - // - bool isValeUnderLast = - // - (conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] && - conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] && - conditions.bars[cIDX].close < conditions.valeBuffer[pIDX]) - // - || - // - (conditions.valeBuffer[pIDX] < conditions.valeBuffer[p2IDX] && - conditions.valeBuffer[p2IDX] >= conditions.valeBuffer[p3IDX] && - conditions.bars[pIDX].close < conditions.valeBuffer[p2IDX]) - // - || - // - (conditions.valeBuffer[p2IDX] < conditions.valeBuffer[p3IDX] && - conditions.valeBuffer[p3IDX] >= conditions.valeBuffer[p4IDX] && - conditions.bars[p2IDX].close < conditions.valeBuffer[p3IDX]) - // - ; - - // - // if (isValeUnderLast) - // { - // Print("SALAM"); - // } - - // - // Try to Summarize Conditions ... - - // - bool isBullishPassed = - // - (isPeakOverLast && - isDeltaBullishStart && - isVolumeBullishStart && - isBarBullishPressured) - // - ; - - // - bool isBearishPassed = - (isValeUnderLast && - isDeltaBearishStart && - isVolumeBearishStart && - isBarBearishPressured) - // - ; - - // - // Try to Detect Trigger Block ... - bool hasTB = false; - int tbLoopback = 100; - X121XCatbInputs mInputs = helper.GetInputs(); - for (int i = barIndex; i < barIndex + tbLoopback; i++) - { - // - // Update Helper ... - helper.Update(i); - - // - // Check TB ... - hasTB = DetectTriggerBlock( - // - conditions.symbol, - conditions.period, - // - tb, - // - drawer, - barAnalyser, - // - // Required Buffers ... - helper.atrBuffer, - helper.rsiBuffer, - helper.adxBuffer, - helper.adxpBuffer, - helper.adxnBuffer, - helper.peakBuffer, - helper.valeBuffer, - helper.deltaBuffer, - helper.sarBuffer, - helper.sarStateBuffer, - helper.trendBuffer, - helper.trendStateBuffer, - helper.atrUpperBuffer, - helper.atrLowerBuffer, - helper.sBarOpenBuffer, - helper.sBarCloseBuffer, - helper.hkSBarOpenBuffer, - helper.hkSBarCloseBuffer, - helper.peakGoldenBuffer, - helper.valeGoldenBuffer, - helper.deltaSignalBuffer, - helper.bullishVolumeSignalBuffer, - helper.bearishVolumeSignalBuffer, - // - i + 1, - // - // Signalling ... - mInputs.signalR2R, - mInputs.slAtrMultiplier, - // - // Configs ... - mInputs.rsiOBLevel, - mInputs.rsiOSLevel, - mInputs.adxThreshold, - // - // Validators ... - mInputs.forceObBarType, - mInputs.forceOBFVGBarType, - mInputs.forceHasSwing, - mInputs.forceHasFLiquidity, - mInputs.forceHasRLiquidity, - mInputs.validateGapSequence, - mInputs.validateBlockEdgeBreakout, - // - // Filters ... - mInputs.filterBasedOnPV, - mInputs.filterBasedOnSar, - mInputs.filterBasedOnRSI, - mInputs.filterBasedOnADX, - mInputs.filterBasedOnATR, - mInputs.filterBasedOnTrend, - mInputs.filterBasedOnDelta, - mInputs.filterBasedOnVolume, - mInputs.filterBasedOnSignalBar, - mInputs.filterBasedOnHKSignalBar // - ); - - // - // Checking Trigger Block Validation ... - hasTB = - // - hasTB && - // - ( - // - (isBullishPassed && - tb.IsBullish()) - // - || - // - (isBearishPassed && - tb.IsBearish()) - // - ); - if (hasTB) - { - // - break; - } - - // - tb.Clean(); - } - - // - // isBullishPassed = false; - // isBearishPassed = false; - - // - // Draw Line for Detect Conditions States on Chart ... - if (hasTB && (isBullishPassed || - isBearishPassed)) - { - // - color iColor = isBullishPassed - ? clrAqua - : clrMagenta; - - // - datetime iTime = conditions.bars[cIDX].time; - - // - string iName = "VL_" + ToFormatString(iTime); - - // - long chartID = drawer.ChartIdentification(); - int subWindow = drawer.SubWindowIdentification(); - - // - CChartObjectVLine *iObj; - iObj = new CChartObjectVLine(); - bool isDrawn = iObj.Create( - chartID, - iName, - subWindow, - iTime // - ); - if (isDrawn) - { - // - iObj.Color(iColor); - } - - // - CArrayObj *tbObjects = new CArrayObj(); - DrawTriggerBlock( - tb, - drawer, - tbObjects, - conditions.bars[0].time // - ); - - // - tb.Clean(); - } - - // - // Summarizing result ... - - // - result = (isBullishPassed || - isBearishPassed); - // // Cleanup Resources ... @@ -1399,7 +1181,7 @@ bool DetectTriggerBlock( if (!result) { // - tb.Clean(); + signalZone.Clean(); conditions.Clean(); } @@ -1416,7 +1198,6 @@ bool DetectTriggerBlock( // XTriggerBlock &tb, // - XCPOIDrawer *drawer, XCBarAnalyser *barAnalyser, // // Required Buffers ... @@ -1456,7 +1237,7 @@ bool DetectTriggerBlock( // // Validators ... // - bool _forceObBarType = false, + bool _forceOBBarType = false, bool _forceFVGBarType = false, bool _forceHasSwing = false, bool _forceHasFLiquidity = false, @@ -1490,7 +1271,7 @@ bool DetectTriggerBlock( // // // // Validators ... // _forceHasSwing = true; - // _forceObBarType = true; + // _forceOBBarType = true; // _forceFVGBarType = true; // _validateGapSequence = true; @@ -1550,7 +1331,7 @@ bool DetectTriggerBlock( zBar, tb.ob, _forceFVGBarType, // Force FVG Bar Type ... - _forceObBarType // Force Block Two Bar Checking ... + _forceOBBarType // Force Block Two Bar Checking ... ); //