From e15c645f01e30ed5eda265ce973daed95381cf75 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 27 May 2025 12:55:30 +0330 Subject: [PATCH] last ... --- Experts/xcatb.test.ea.mq5 | 327 ++++++--- Libraries/x-saherelm.x121.xcatb.lib.mq5 | 898 +++++++++++++++++++++++- 2 files changed, 1084 insertions(+), 141 deletions(-) diff --git a/Experts/xcatb.test.ea.mq5 b/Experts/xcatb.test.ea.mq5 index 670b803a..ff84c224 100644 --- a/Experts/xcatb.test.ea.mq5 +++ b/Experts/xcatb.test.ea.mq5 @@ -91,10 +91,12 @@ input double eaConstantBalance = 0.0; // Constant Ba // // Management ... +// eaSessions => (SYDNEY_02:00_14:00),(NY_19:00_23:00) input group "Management"; input bool eaAllowTrade = true; // Allow Trade on Signals 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 @@ -233,6 +235,11 @@ void OnDeinit(const int reason) // On Tick Handler ... void OnTick() { + // + // Handle Tradings ... + bool tradeUsingTriggerBlock = true; + bool tradeUsingMarketConditions1 = true; + // HandleTimeReport(); @@ -290,136 +297,164 @@ void OnTick() // // Check Trigger Block Detected or Not ... - XTriggerBlock iTB; - X121XCatbConditions iConditions; - - // - // has = DetectTriggerBlock( - // // - // _Symbol, - // _Period, - // // - // iTB, - // // - // 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, - iConditions, - iTB, - barIndex, - 10 // - ); - - // - if (has) + if (tradeUsingTriggerBlock) { // - eaBarTraker.Waits(); - - // - eaSignal = iTB.signal; - - // - // Here we Can Fill eaConditions ... - - // - // Check Signal Type ... - bool isLong = IsLong(eaSignal.type); - - // - // Update Entry ... - eaSignal.entry = GetEntry( - eaSignal.symbol, - eaSignal.type // + 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 // ); // - // Update Signal Targets ... - UpdateSignalTargets(eaSignal); + // has = DetectTriggerBlock( + // eaDrawer, + // eaHelper, + // eaBarAnalyser, + // iConditions, + // iTB, + // barIndex, + // 10 // + // ); // - // Handle Volume Management ... - double iVolume = eaVolume.CalculateVolume(eaSignal); - if (iVolume > X_MIN_VOLUME && - iVolume != eaSignal.volume) + if (has) { - eaSignal.volume = iVolume; + // + eaBarTraker.Waits(); + + // + eaSignal = iTB.signal; + + // + // Here we Can Fill eaConditions ... + + // + // Check Signal Type ... + bool isLong = IsLong(eaSignal.type); + + // + // Update Entry ... + eaSignal.entry = GetEntry( + eaSignal.symbol, + eaSignal.type // + ); + + // + // Update Signal Targets ... + UpdateSignalTargets(eaSignal); + + // + // Handle Volume Management ... + double iVolume = eaVolume.CalculateVolume(eaSignal); + if (iVolume > X_MIN_VOLUME && + iVolume != eaSignal.volume) + { + eaSignal.volume = iVolume; + } + + // + // Execute Signal ... + has = eaTradeManager.Execute( + eaSignal, + eaConditions // + ); } // - // Execute Signal ... - has = eaTradeManager.Execute( - eaSignal, - eaConditions // + iTB.Clean(); + } + + // + // Trade Using Market Conditions ... + if (tradeUsingMarketConditions1) + { + // + XBoxZone signalZone; + X121XCatbConditions conditions; + has = DetectSignalZone1( + eaDrawer, + eaHelper, + eaBarAnalyser, + signalZone, + conditions, + barIndex // ); + if (has) + { + // + // Convert Box to Signal ... + } } // // Cleanup Resources ... // - iTB.Clean(); zBar.Clean(); cBar.Clean(); } @@ -799,6 +834,74 @@ void InitRequirements() eaMaxAllowedSLs, eaMaxAllowedTrades // ); + + // + // Initializing Sessions ... + string sessions[]; + int sessionsCount = 0; + bool hasSession = IsValid(eaSessions); + if (hasSession) + { + // + // Extract Per Symbol Sessions ... + sessionsCount = SplitContent( + sessions, + eaSessions, + "," // + ); + + // + // Try to Extract Start and End Times Series ... + hasSession = IsValidSize(sessionsCount); + if (hasSession) + { + // + // Iterate Sessions ... + for (int i = 0; i < sessionsCount; i++) + { + // + // Ignore unused Cases and Extracts only Content ... + string iSessionDescriptorStr = ExtractString(sessions[i]); + isInited = IsValid(iSessionDescriptorStr); + if (isInited) + { + // + // Extract Session Descriptor Data ... + string parts[]; + int partsCount = SplitContent( + parts, + iSessionDescriptorStr, + "_" // + ); + isInited = IsValidSize(partsCount) && partsCount == 3; + if (isInited) + { + // + string iName = parts[0]; + string iStart = parts[1]; + string iEnd = parts[2]; + isInited = IsValid(iName) && + IsValid(iStart) && + IsValid(iEnd); + if (isInited) + { + // + // Set Active Session ... + eaTradeManager + .SetTradeSession( + _Symbol, + iStart, + iEnd, + iName // + ); + } + } + } + } + } + } + + // } /** diff --git a/Libraries/x-saherelm.x121.xcatb.lib.mq5 b/Libraries/x-saherelm.x121.xcatb.lib.mq5 index 85da990b..a23fa9b3 100644 --- a/Libraries/x-saherelm.x121.xcatb.lib.mq5 +++ b/Libraries/x-saherelm.x121.xcatb.lib.mq5 @@ -136,11 +136,13 @@ struct XTriggerBlock // // Extensions ... -bool DetectTriggerBlock( - XCPOIDrawer *drawer, +// +bool DetectSignalZone1( + XCPOIDrawer *&drawer, XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XBoxZone &signalZone, X121XCatbConditions &conditions, - XTriggerBlock &tb, int barIndex = 0, int loopback = 10 // ) @@ -148,16 +150,20 @@ bool DetectTriggerBlock( // bool result = false; + // + // Checking Conditions ... + // // Normalize Args ... - tb.Clean(); + signalZone.Clean(); conditions.Clean(); barIndex = NormalizeInt(barIndex, 0); loopback = NormalizeInt(loopback, 0); // // Validate Args ... - result = helper != NULL; + result = helper != NULL && + barAnalyser != NULL; if (!result) { return result; @@ -173,7 +179,7 @@ bool DetectTriggerBlock( if (!result) { // - tb.Clean(); + signalZone.Clean(); conditions.Clean(); } @@ -182,10 +188,75 @@ bool DetectTriggerBlock( 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 ... @@ -542,41 +613,734 @@ bool DetectTriggerBlock( // ; + // + // 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]) + // + ; + + // + bool isValeUnderLast = + // + (conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] && + conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] && + conditions.bars[cIDX].close < conditions.valeBuffer[pIDX]) + // + ; + + // + // Start Different Conditions Implemntation ... + + // + // Condition 1: + // --------------------------- + // Descriptions: + // + // + // --------------------------- + + // + // Bullish ... + bool isCond1Bullish = false; + + // + // Bearish ... + bool isCond1Bearish = false; + // // Try to Summarize Conditions ... // bool isBullishPassed = // - //isSarBullishStart && - // isTrendBullishStart && - // isADXBullishStart && - isDeltaBullishStart && - isVolumeBullishStart && - isSBarBullishStart - // && - // isHKSBarBullishStart + isCond1Bullish // ; // bool isBearishPassed = // - // isSarBearishStart && - // isTrendBearishStart && - // isADXBearishStart && - isDeltaBearishStart && - isVolumeBearishStart && - isSBarBearishStart - // && - // isHKSBarBearishStart + isCond1Bearish // ; + // + // 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) + { + // + 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 (isBullishPassed || - isBearishPassed) + if (hasTB && (isBullishPassed || + isBearishPassed)) { // color iColor = isBullishPassed @@ -607,6 +1371,18 @@ bool DetectTriggerBlock( // iObj.Color(iColor); } + + // + CArrayObj *tbObjects = new CArrayObj(); + DrawTriggerBlock( + tb, + drawer, + tbObjects, + conditions.bars[0].time // + ); + + // + tb.Clean(); } // @@ -640,6 +1416,7 @@ bool DetectTriggerBlock( // XTriggerBlock &tb, // + XCPOIDrawer *drawer, XCBarAnalyser *barAnalyser, // // Required Buffers ... @@ -1072,13 +1849,18 @@ bool DetectTriggerBlock( double iP2ValeGolden = _valeGoldenBuffer[barIndex + 2]; // + // TODO: Fix this ... has = has && (isBullish - ? (tb.trigger.lower <= iVale || - tb.trigger.lower <= iValeGolden) - : (tb.trigger.upper >= iPeak || - tb.trigger.upper >= iPeakGolden)); + ? (tb.trigger.lower <= iVale && + tb.trigger.upper < iPeak + // || tb.trigger.lower <= iValeGolden + ) + : (tb.trigger.upper >= iPeak && + tb.trigger.lower > iVale + // || tb.trigger.upper >= iPeakGolden + )); } // @@ -1488,10 +2270,63 @@ bool DetectTriggerBlock( : isHKSignalBarSwitchedToBearish); } + // + // Valdating Directional Trending ... + bool _filterBasedOnDirection = false; + if (has && + _filterBasedOnDirection) + { + // + iBar.Clean(); + fromIDX = tb.FromIndex(); + int loopbackForValidating = 30; + for (int i = fromIDX; i < fromIDX + loopbackForValidating; i++) + { + // + // Initialize iBar ... + iBar.Clean(); + has = iBar.Init( + symbol, + period, + i // + ); + + // + has = + has && + (isBullish + ? iBar.high < tb.trigger.upper + : iBar.low > tb.trigger.lower); + if (!has) + { + break; + } + } + + // + // Update Trigger Block ... + if (has) + { + tb.trigger.from = iBar.time; + } + + // + iBar.Clean(); + } + // // Preparing Signal ... if (has) { + // + // CArrayObj *tbObjects = new CArrayObj(); + // DrawTriggerBlock( + // tb, + // drawer, + // tbObjects, + // NULL // + // ); + // double targets[]; for (int i = 1; i <= _r2r; i++) @@ -1504,7 +2339,12 @@ bool DetectTriggerBlock( } // - double iATR = _atrBuffer[barIndex]; + double iATR = 0; + if (barIndex > 0 && + barIndex < ArraySize(_atrBuffer)) + { + iATR = _atrBuffer[barIndex]; + } double slAdditional = _slAtrMultiplier * iATR; //