diff --git a/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Helpers/x-saherelm.x121.xcatb.helper.mq5 index 100b596b..d596f8ec 100644 --- a/Helpers/x-saherelm.x121.xcatb.helper.mq5 +++ b/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -33,7 +33,7 @@ enum ENUM_X121_XCATB_BUFFERS { X121_XCATB_SAR_LINE = 0, - X121_XCATB_SAR_STATE_LINE = 30, + X121_XCATB_SAR_COLOR_LINE = 1, X121_XCATB_PEAK_LINE = 2, X121_XCATB_VALE_LINE = 3, X121_XCATB_PEAK_GOLDEN_LINE = 4, @@ -41,15 +41,17 @@ enum ENUM_X121_XCATB_BUFFERS X121_XCATB_ATR_BAND_UPPER_LINE = 6, X121_XCATB_ATR_BAND_LOWER_LINE = 7, X121_XCATB_TREND_LINE = 8, - X121_XCATB_TREND_STATE_LINE = 31, + X121_XCATB_TREND_COLOR_LINE = 9, X121_XCATB_SBAR_O_LINE = 10, X121_XCATB_SBAR_H_LINE = 11, X121_XCATB_SBAR_L_LINE = 12, X121_XCATB_SBAR_C_LINE = 13, + X121_XCATB_SBAR_COLOR_LINE = 14, X121_XCATB_HK_SBAR_O_LINE = 15, X121_XCATB_HK_SBAR_H_LINE = 16, X121_XCATB_HK_SBAR_L_LINE = 17, X121_XCATB_HK_SBAR_C_LINE = 18, + X121_XCATB_HK_SBAR_COLOR_LINE = 19, X121_XCATB_S_HH_LINE = 20, X121_XCATB_S_LL_LINE = 21, X121_XCATB_M_HH_LINE = 22, @@ -59,7 +61,9 @@ enum ENUM_X121_XCATB_BUFFERS X121_XCATB_H_HH_LINE = 26, X121_XCATB_H_LL_LINE = 27, X121_XCATB_KI_LINE = 28, - X121_XCATB_KI_STATE_LINE = 50, + X121_XCATB_KI_COLOR_LINE = 29, + X121_XCATB_SAR_STATE_LINE = 30, + X121_XCATB_TREND_STATE_LINE = 31, X121_XCATB_RSI_LINE = 32, X121_XCATB_ADX_LINE = 33, X121_XCATB_ADXP_LINE = 34, @@ -77,6 +81,7 @@ enum ENUM_X121_XCATB_BUFFERS X121_XCATB_HK_BAR_H_LINE = 46, X121_XCATB_HK_BAR_L_LINE = 47, X121_XCATB_HK_BAR_C_LINE = 48, + X121_XCATB_KI_STATE_LINE = 49, }; // @@ -352,6 +357,10 @@ struct X121XCatbConditions // // KI ... + // + bool isKIUp; + bool isKIDown; + // bool isKIBullish; bool isKIBearish; @@ -634,6 +643,10 @@ struct X121XCatbConditions // // KI ... + // + isKIUp = false; + isKIDown = false; + // isKIBullish = false; isKIBearish = false; @@ -843,6 +856,10 @@ struct X121XCatbConditions // KI ... // + if (isKIUp) + { + bullishScore += score; + } if (isKIBullish) { bullishScore += score; @@ -853,6 +870,10 @@ struct X121XCatbConditions } // + if (isKIDown) + { + bearishScore += score; + } if (isKIBearish) { bearishScore += score; @@ -1186,6 +1207,8 @@ struct X121XCatbConditions "-----------------------" + separator + "KI: " + separator + "-----------------------" + separator + + ToString("isKIUp", isKIUp, ignoreFalseConditions, separator) + + ToString("isKIDown", isKIDown, ignoreFalseConditions, separator) + ToString("isKIBullish", isKIBullish, ignoreFalseConditions, separator) + ToString("isKIBearish", isKIBearish, ignoreFalseConditions, separator) + ToString("isKISameAsLast", isKISameAsLast, ignoreFalseConditions, separator) + @@ -4688,6 +4711,10 @@ class XCX121XCatbHelper : public XCBaseHelper // // KI ... + // + bool isKIUp = cKI > pKI; + bool isKIDown = cKI < pKI; + // bool isKIBullish = cKIState > 0; bool isKIBearish = cKIState < 0; @@ -4971,9 +4998,11 @@ class XCX121XCatbHelper : public XCBaseHelper // Attached ... // + conditions.isKIUp = isKIUp; conditions.isATRUp = isATRUp; conditions.isRSIOB = isRSIOB; conditions.isRSIOS = isRSIOS; + conditions.isKIDown = isKIDown; conditions.isDeltaUp = isDeltaUp; conditions.isATRDown = isATRDown; conditions.isTrendUp = isTrendUp; @@ -4983,13 +5012,13 @@ class XCX121XCatbHelper : public XCBaseHelper conditions.isTrendDown = isTrendDown; conditions.isKIBullish = isKIBullish; conditions.isKIBearish = isKIBearish; - conditions.adxThreshold = _adxThreshold; conditions.isSarBullish = isSarBullish; conditions.isSarBearish = isSarBearish; conditions.isADXBullish = isADXBullish; conditions.isADXBearish = isADXBearish; conditions.isRSIBullish = isRSIBullish; conditions.isRSIBearish = isRSIBearish; + conditions.adxThreshold = _adxThreshold; conditions.isSBarBullish = isSBarBullish; conditions.isSBarBearish = isSBarBearish; conditions.isKISameAsLast = isKISameAsLast; diff --git a/Indicators/x-saherelm.x121.xcatb.mq5 b/Indicators/x-saherelm.x121.xcatb.mq5 index 86607b9f..81c63b57 100644 --- a/Indicators/x-saherelm.x121.xcatb.mq5 +++ b/Indicators/x-saherelm.x121.xcatb.mq5 @@ -145,8 +145,8 @@ ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method // Plot: 18 // Color: 4 // Bar: 8 -// Data Buffer: 19 -#property indicator_buffers 52 +// Data Buffer: 29 +#property indicator_buffers 50 #property indicator_plots 19 // @@ -1422,7 +1422,7 @@ void DefineBuffers() // ArraySetAsSeries(kiStateBuffer, true); - SetIndexBuffer(kiStateBufferIndex, kiStateBuffer, INDICATOR_DATA); + SetIndexBuffer(kiStateBufferIndex, kiStateBuffer, INDICATOR_CALCULATIONS); // } diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index e100659e..f90862fc 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -150,6 +150,20 @@ enum ENUM_X_POSITION_TYPES X_POSITION_TYPE_SHORT = 3, }; +// +bool IsValid(ENUM_X_POSITION_TYPES value) +{ + return value != X_POSITION_TYPE_NONE; +} + +// +bool HasSpecifiedType(ENUM_X_POSITION_TYPES value) +{ + // + return value == X_POSITION_TYPE_LONG || + value == X_POSITION_TYPE_SHORT; +} + // string ToString(ENUM_X_POSITION_TYPES value) { @@ -190,6 +204,12 @@ bool IsLong(ENUM_X_POSITION_TYPES value) return value == X_POSITION_TYPE_LONG; } +// +bool IsShort(ENUM_X_POSITION_TYPES value) +{ + return value == X_POSITION_TYPE_SHORT; +} + // bool ToPositionType( ENUM_POSITION_TYPE &dest, @@ -3096,7 +3116,7 @@ struct XSymbolPositions if (isLong) { // - result = FindMaxInDrawdownIndex( + result = FindMaxDrawdownIndex( longs // ); @@ -3109,7 +3129,7 @@ struct XSymbolPositions else { // - result = FindMaxInDrawdownIndex( + result = FindMaxDrawdownIndex( shorts // ); @@ -3150,7 +3170,7 @@ struct XSymbolPositions if (isLong) { // - result = FindMinInDrawdownIndex( + result = FindMinDrawdownIndex( longs // ); @@ -3163,7 +3183,7 @@ struct XSymbolPositions else { // - result = FindMinInDrawdownIndex( + result = FindMinDrawdownIndex( shorts // ); @@ -3755,7 +3775,7 @@ int ExtractInProfitPositions( } // -int FindMaxInDrawdownIndex( +int FindMaxDrawdownIndex( XPosition &positions[] // Position Collection ) { @@ -3795,7 +3815,7 @@ int FindMaxInDrawdownIndex( } // -int FindMinInDrawdownIndex( +int FindMinDrawdownIndex( XPosition &positions[] // Position Collection ) { diff --git a/XCATBEA/Classes/xcatbea.expert.class.mq5 b/XCATBEA/Classes/xcatbea.expert.class.mq5 index eb1b0b59..35db51bc 100644 --- a/XCATBEA/Classes/xcatbea.expert.class.mq5 +++ b/XCATBEA/Classes/xcatbea.expert.class.mq5 @@ -480,10 +480,12 @@ class XCXCATBEAExpert : public XCBase // // Make Available all Requirement Buffers of XCATB indicator ... - iSignallerInputs.catbInputs.showPV = true; - iSignallerInputs.catbInputs.showKI = true; - iSignallerInputs.catbInputs.showATRBand = true; - iSignallerInputs.catbInputs.showPVGolden = true; + iSignallerInputs.catbInputs.showPV = false; + iSignallerInputs.catbInputs.showKI = false; + iSignallerInputs.catbInputs.showSar = false; + iSignallerInputs.catbInputs.showTrend = false; + iSignallerInputs.catbInputs.showATRBand = false; + iSignallerInputs.catbInputs.showPVGolden = false; // // Signalling Configurations ... diff --git a/XCATBEA/Classes/xcatbea.signaller.class.mq5 b/XCATBEA/Classes/xcatbea.signaller.class.mq5 index 3f3ceab1..e850654f 100644 --- a/XCATBEA/Classes/xcatbea.signaller.class.mq5 +++ b/XCATBEA/Classes/xcatbea.signaller.class.mq5 @@ -35,6 +35,7 @@ // Definitions ... // +// Configure Signalelrs ... struct XCATBEASignallingConfigs { // @@ -374,6 +375,10 @@ class XCXCATBEASignaller : XCBase barIndex // ); + // + // Check Helper Last Changes ... + helper.Check(barIndex); + // // Draw POI(s) ... if (allowDraws) @@ -676,8 +681,7 @@ class XCXCATBEASignaller : XCBase // // Validate Vale ... - bool isValid = cVale.upper < cTriggerBlock.trigger.lower && - cVale.upper < cInsideTriggerBlock.trigger.lower; + bool isValid = cVale.upper < cBar.low; if (isValid) { break; @@ -698,7 +702,11 @@ class XCXCATBEASignaller : XCBase // // Detect Signalling Zone ... result = DetectSignalZone( + cPeak, + cVale, helper, + drawer, + detector, barAnalyser, mConditions.conditions, mConditions.pivotZone, @@ -1879,8 +1887,18 @@ class XCXCATBEASignaller : XCBase // // Configure ... + + // detector.detectPeakPivots = true; detector.detectValePivots = true; + + // + detector.detectMTBullishPivots = true; + detector.detectMTBearishPivots = true; + + // + detector.detectOBBullishPivots = true; + detector.detectOBBearishPivots = true; } // @@ -1926,4 +1944,6 @@ class XCXCATBEASignaller : XCBase } // -}; \ No newline at end of file +}; + +// \ No newline at end of file diff --git a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 index 39734bb8..7f9d7448 100644 --- a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 +++ b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 @@ -32,9 +32,13 @@ // enum ENUM_XCATB_PIVOTS { - XCA_NONE, // None - XCA_PEAK, // Peak - XCA_VALE, // Vale + XCATB_NONE, // None + XCATB_PEAK, // Peak + XCATB_VALE, // Vale + XCATB_BULLISH_MT, // MTBull + XCATB_BEARISH_MT, // MTBear + XCATB_BULLISH_OB, // OBBull + XCATB_BEARISH_OB, // OBBear }; // @@ -44,7 +48,7 @@ bool IsValid(ENUM_XCATB_PIVOTS value) bool result = false; // - result = value != XCA_NONE; + result = value != XCATB_NONE; // return result; @@ -73,12 +77,16 @@ ENUM_X_DIRECTION GetDirection(ENUM_XCATB_PIVOTS value) switch (value) { // - case XCA_VALE: + case XCATB_VALE: + case XCATB_BULLISH_MT: + case XCATB_BULLISH_OB: result = X_DIRECTION_BULLISH; break; // - case XCA_PEAK: + case XCATB_PEAK: + case XCATB_BEARISH_MT: + case XCATB_BEARISH_OB: result = X_DIRECTION_BEARISH; break; } @@ -97,10 +105,22 @@ string GetBoxType(ENUM_XCATB_PIVOTS value) switch (value) { // - case XCA_VALE: - case XCA_PEAK: + case XCATB_VALE: + case XCATB_PEAK: result = ToString(value); break; + + // + case XCATB_BULLISH_MT: + case XCATB_BEARISH_MT: + result = "XMT"; + break; + + // + case XCATB_BULLISH_OB: + case XCATB_BEARISH_OB: + result = "XOB"; + break; } // @@ -111,7 +131,7 @@ string GetBoxType(ENUM_XCATB_PIVOTS value) ENUM_XCATB_PIVOTS GetPivotType(XBoxZone &value) { // - ENUM_XCATB_PIVOTS result = XCA_NONE; + ENUM_XCATB_PIVOTS result = XCATB_NONE; // bool has = value.IsValid(); @@ -121,19 +141,43 @@ ENUM_XCATB_PIVOTS GetPivotType(XBoxZone &value) } // - bool isPeak = value.type == GetBoxType(XCA_PEAK) && - value.dir == GetDirection(XCA_PEAK); - bool isVale = value.type == GetBoxType(XCA_VALE) && - value.dir == GetDirection(XCA_VALE); + bool isPeak = value.type == GetBoxType(XCATB_PEAK) && + value.dir == GetDirection(XCATB_PEAK); + bool isVale = value.type == GetBoxType(XCATB_VALE) && + value.dir == GetDirection(XCATB_VALE); + bool isBullishMT = value.type == GetBoxType(XCATB_BULLISH_MT) && + value.dir == GetDirection(XCATB_BULLISH_MT); + bool isBearishMT = value.type == GetBoxType(XCATB_BEARISH_MT) && + value.dir == GetDirection(XCATB_BEARISH_MT); + bool isBullishOB = value.type == GetBoxType(XCATB_BULLISH_OB) && + value.dir == GetDirection(XCATB_BULLISH_OB); + bool isBearishOB = value.type == GetBoxType(XCATB_BEARISH_OB) && + value.dir == GetDirection(XCATB_BEARISH_OB); // if (isPeak) { - result = XCA_PEAK; + result = XCATB_PEAK; } else if (isVale) { - result = XCA_VALE; + result = XCATB_VALE; + } + else if (isBullishMT) + { + result = XCATB_BULLISH_MT; + } + else if (isBearishMT) + { + result = XCATB_BEARISH_MT; + } + else if (isBullishOB) + { + result = XCATB_BULLISH_OB; + } + else if (isBearishOB) + { + result = XCATB_BEARISH_OB; } // @@ -178,7 +222,7 @@ struct XCATBPivot from = NULL; symbol = NULL; period = NULL; - type = XCA_NONE; + type = XCATB_NONE; // Clean(values); @@ -517,6 +561,14 @@ class XCXCATBEAPOIDetector : public XCBase // detectPeakPivots = false; detectValePivots = false; + + // + detectMTBullishPivots = false; + detectMTBearishPivots = false; + + // + detectOBBullishPivots = false; + detectOBBearishPivots = false; } // @@ -544,6 +596,10 @@ class XCXCATBEAPOIDetector : public XCBase // newPeakPivotDetected = false; newValePivotDetected = false; + newMTBullishPivotDetected = false; + newMTBearishPivotDetected = false; + newOBBullishPivotDetected = false; + newOBBearishPivotDetected = false; // int index = barIndex; @@ -636,6 +692,76 @@ class XCXCATBEAPOIDetector : public XCBase ); } + // + // MT ... + + // + // Bullish ... + if (detectMTBullishPivots) + { + // + newMTBullishPivotDetected = DetectMTPivot( + barIndex, + X_DIRECTION_BULLISH, + zBar, + cBar, + pBar, + p2Bar, + conditions // + ); + } + + // + // Bearish ... + if (detectMTBearishPivots) + { + // + newMTBearishPivotDetected = DetectMTPivot( + barIndex, + X_DIRECTION_BEARISH, + zBar, + cBar, + pBar, + p2Bar, + conditions // + ); + } + + // + // OB ... + + // + // Bullish ... + if (detectOBBullishPivots) + { + // + newOBBullishPivotDetected = DetectOBPivot( + barIndex, + X_DIRECTION_BULLISH, + zBar, + cBar, + pBar, + p2Bar, + conditions // + ); + } + + // + // Bearish ... + if (detectOBBearishPivots) + { + // + newOBBearishPivotDetected = DetectOBPivot( + barIndex, + X_DIRECTION_BEARISH, + zBar, + cBar, + pBar, + p2Bar, + conditions // + ); + } + // // Others ... @@ -670,6 +796,20 @@ class XCXCATBEAPOIDetector : public XCBase barIndex // ); + // + // MT ... + ValidateMTPivots( + unavailables, + barIndex // + ); + + // + // OB ... + ValidateOBPivots( + unavailables, + barIndex // + ); + // SortPivots(); } @@ -687,6 +827,14 @@ class XCXCATBEAPOIDetector : public XCBase // Clean(peakPivots); Clean(valePivots); + + // + Clean(mtBullishPivots); + Clean(mtBearishPivots); + + // + Clean(obBullishPivots); + Clean(obBearishPivots); } // @@ -1043,7 +1191,7 @@ class XCXCATBEAPOIDetector : public XCBase valePivot.Clean(); // - valePivot.type = XCA_VALE; + valePivot.type = XCATB_VALE; valePivot.symbol = symbol; valePivot.period = period; @@ -1062,7 +1210,7 @@ class XCXCATBEAPOIDetector : public XCBase peakPivot.Clean(); // - peakPivot.type = XCA_PEAK; + peakPivot.type = XCATB_PEAK; peakPivot.symbol = symbol; peakPivot.period = period; @@ -1357,6 +1505,699 @@ class XCXCATBEAPOIDetector : public XCBase return result; } + // + // MITIGATIONBLOCK ... + + // + int maxAllowedMTLifetime; // Max Allowed MT Life ... + + // + bool DetectMTPivot( + int barIndex, + ENUM_X_DIRECTION forDir, + XOHCL &zBar, + XOHCL &cBar, + XOHCL &pBar, + XOHCL &p2Bar, + X121XCatbConditions &conditions // + ) + { + // + bool result = false; + + // + // Checking Direction ... + result = HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool forBullish = IsBullish(forDir); + bool forBearish = IsBearish(forDir); + + // + // Check Allowed ... + result = + forBullish + ? detectMTBullishPivots + : detectMTBearishPivots; + if (!result) + { + return result; + } + + // + // Validate Args ... + result = + // + barIndex >= 0 && + zBar.IsValid() && + cBar.IsValid() && + pBar.IsValid() && + p2Bar.IsValid() + // + ; + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + + // + datetime cTime = zBar.time; + string symbol = zBar.symbol; + ENUM_TIMEFRAMES period = zBar.period; + double points = GetPoints(symbol); + + // + // Detecting Bar Conditions ... + + // + ENUM_X_DIRECTION cBarDir; + + // + // Rejected ... + bool isCBarRejected = barAnalyser + .IsRejected( + cBar, + cBarDir, + false, // Force Type ... + true // Force Fibo Pressure ... + ); + + // + bool isCBarBullishRejected = + forBullish && + isCBarRejected && + IsBullish(cBarDir); + bool isCBarBearishRejected = + forBearish && + isCBarRejected && + IsBearish(cBarDir); + + // + // Prepare Conditinal Conditions ... + + // + // Summarizing Conditions ... + + // + result = false; + + // + bool hasEndCondition = + // + forBullish + ? isCBarBullishRejected + : isCBarBearishRejected + // + ; + + // + // End up Pivot and Store it ... + if (hasEndCondition) + { + // + XBoxZone iPivot; + iPivot.to = zBar.time; + iPivot.from = cBar.time; + iPivot.symbol = cBar.symbol; + iPivot.period = cBar.period; + + // + // Bullish ... + if (forBullish) + { + // + iPivot.lower = cBar.low; + iPivot.upper = cBar.GetDown(); + iPivot.dir = X_DIRECTION_BULLISH; + iPivot.type = GetBoxType(XCATB_BULLISH_MT); + + // + result = iPivot.IsValid(); + if (result) + { + // + newMTBullishPivotDetected = AddBox( + iPivot, + mtBullishPivots // + ); + } + } + + // + // Bearish ... + if (forBearish) + { + // + iPivot.upper = cBar.high; + iPivot.lower = cBar.GetUp(); + iPivot.dir = X_DIRECTION_BEARISH; + iPivot.type = GetBoxType(XCATB_BEARISH_MT); + + // + result = iPivot.IsValid(); + if (result) + { + // + newMTBearishPivotDetected = AddBox( + iPivot, + mtBearishPivots // + ); + } + } + } + + // + return result; + } + + // + void ValidateMTPivots( + XBoxZone &unavailables[], + int barIndex = 0 // + ) + { + // + bool has = false; + + // + bool applyLifetimeValidating = maxAllowedMTLifetime > 0; + + // + // Bullish ... + has = HasMTBullishPivots(); + if (has) + { + // + ApplyValidationOnBoxes( + mtBullishPivots, + unavailables, + barIndex // + ); + + // + if (applyLifetimeValidating) + { + // + ApplyLifeTimeValidationOnBoxes( + mtBullishPivots, + maxAllowedMTLifetime, + barIndex // + ); + } + } + + // + // Bearish ... + has = HasMTBearishPivots(); + if (has) + { + // + ApplyValidationOnBoxes( + mtBearishPivots, + unavailables, + barIndex // + ); + + // + if (applyLifetimeValidating) + { + // + ApplyLifeTimeValidationOnBoxes( + mtBearishPivots, + maxAllowedMTLifetime, + barIndex // + ); + } + } + } + + // + // Bullish ... + XBoxZone mtBullishPivots[]; + bool detectMTBullishPivots; + bool newMTBullishPivotDetected; + + // + bool HasMTBullishPivots() + { + return HasChild(mtBullishPivots); + } + + // + int CountMTBullishPivots() + { + return ArraySize(mtBullishPivots); + } + + // + int FillMTBullishPivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasMTBullishPivots()) + { + return result; + } + + // + int count = CountMTBullishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = mtBullishPivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + + // + // Bearish ... + XBoxZone mtBearishPivots[]; + bool detectMTBearishPivots; + bool newMTBearishPivotDetected; + + // + bool HasMTBearishPivots() + { + return HasChild(mtBearishPivots); + } + + // + int CountMTBearishPivots() + { + return ArraySize(mtBearishPivots); + } + + // + int FillMTBearishPivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasMTBearishPivots()) + { + return result; + } + + // + int count = CountMTBearishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = mtBearishPivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + + // + // ORDERBLOCK ... + + // + int maxAllowedOBLifetime; // Max Allowed MT Life ... + + // + bool DetectOBPivot( + int barIndex, + ENUM_X_DIRECTION forDir, + XOHCL &zBar, + XOHCL &cBar, + XOHCL &pBar, + XOHCL &p2Bar, + X121XCatbConditions &conditions // + ) + { + // + bool result = false; + + // + // Checking Direction ... + result = HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool forBullish = IsBullish(forDir); + bool forBearish = IsBearish(forDir); + + // + // Check Allowed ... + result = + forBullish + ? detectOBBullishPivots + : detectOBBearishPivots; + if (!result) + { + return result; + } + + // + // Validate Args ... + result = + // + barIndex >= 0 && + zBar.IsValid() && + cBar.IsValid() && + pBar.IsValid() && + p2Bar.IsValid() + // + ; + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + + // + datetime cTime = zBar.time; + string symbol = zBar.symbol; + ENUM_TIMEFRAMES period = zBar.period; + double points = GetPoints(symbol); + + // + XBoxZone iPivot; + + // + // Detecting Bar Conditions ... + + // + + // + // OB ... + bool isOB = barAnalyser + .IsOB( + cBar, + iPivot, + false, + false // + ); + + // + bool isBullishOB = + isOB && + iPivot.IsBullish(); + bool isBearishOB = + isOB && + iPivot.IsBearish(); + + // + // Prepare Conditinal Conditions ... + + // + // Summarizing Conditions ... + + // + result = false; + + // + bool hasEndCondition = + // + forBullish + ? isBullishOB + : isBearishOB + // + ; + + // + // End up Pivot and Store it ... + if (hasEndCondition) + { + // + // Bullish ... + if (forBullish) + { + // + iPivot.type = GetBoxType(XCATB_BULLISH_OB); + + // + result = iPivot.IsValid(); + if (result) + { + // + newOBBullishPivotDetected = AddBox( + iPivot, + obBullishPivots // + ); + } + } + + // + // Bearish ... + if (forBearish) + { + // + iPivot.type = GetBoxType(XCATB_BEARISH_OB); + + // + result = iPivot.IsValid(); + if (result) + { + // + newOBBearishPivotDetected = AddBox( + iPivot, + obBearishPivots // + ); + } + } + } + + // + return result; + } + + // + void ValidateOBPivots( + XBoxZone &unavailables[], + int barIndex = 0 // + ) + { + // + bool has = false; + + // + bool applyLifetimeValidating = maxAllowedOBLifetime > 0; + + // + // Bullish ... + has = HasOBBullishPivots(); + if (has) + { + // + ApplyValidationOnBoxes( + obBullishPivots, + unavailables, + barIndex // + ); + + // + if (applyLifetimeValidating) + { + // + ApplyLifeTimeValidationOnBoxes( + obBullishPivots, + maxAllowedOBLifetime, + barIndex // + ); + } + } + + // + // Bearish ... + has = HasOBBearishPivots(); + if (has) + { + // + ApplyValidationOnBoxes( + obBearishPivots, + unavailables, + barIndex // + ); + + // + if (applyLifetimeValidating) + { + // + ApplyLifeTimeValidationOnBoxes( + obBearishPivots, + maxAllowedOBLifetime, + barIndex // + ); + } + } + } + + // + // Bullish ... + XBoxZone obBullishPivots[]; + bool detectOBBullishPivots; + bool newOBBullishPivotDetected; + + // + bool HasOBBullishPivots() + { + return HasChild(obBullishPivots); + } + + // + int CountOBBullishPivots() + { + return ArraySize(obBullishPivots); + } + + // + int FillOBBullishPivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasOBBullishPivots()) + { + return result; + } + + // + int count = CountOBBullishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = obBullishPivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + + // + // Bearish ... + XBoxZone obBearishPivots[]; + bool detectOBBearishPivots; + bool newOBBearishPivotDetected; + + // + bool HasOBBearishPivots() + { + return HasChild(obBearishPivots); + } + + // + int CountOBBearishPivots() + { + return ArraySize(obBearishPivots); + } + + // + int FillOBBearishPivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasOBBearishPivots()) + { + return result; + } + + // + int count = CountOBBearishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = obBearishPivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + // // Protected ... protected: @@ -1638,6 +2479,38 @@ class XCXCATBEAPOIDetector : public XCBase { ApplySortOnBoxes(valePivots); } + + // + // MT Bullish ... + has = HasMTBullishPivots(); + if (has) + { + ApplySortOnBoxes(mtBullishPivots); + } + + // + // MT Bearish ... + has = HasMTBearishPivots(); + if (has) + { + ApplySortOnBoxes(mtBearishPivots); + } + + // + // OB Bullish ... + has = HasOBBullishPivots(); + if (has) + { + ApplySortOnBoxes(obBullishPivots); + } + + // + // OB Bearish ... + has = HasOBBearishPivots(); + if (has) + { + ApplySortOnBoxes(obBearishPivots); + } } // diff --git a/XCATBEA/Classes/xcatbea.x-poi.drawer.class.mq5 b/XCATBEA/Classes/xcatbea.x-poi.drawer.class.mq5 index f55934f3..32c8fa05 100644 --- a/XCATBEA/Classes/xcatbea.x-poi.drawer.class.mq5 +++ b/XCATBEA/Classes/xcatbea.x-poi.drawer.class.mq5 @@ -84,6 +84,10 @@ class XCXCATBEAPOIDrawer : public XCBase // Drawers ... bool drawPeakPivots; bool drawValePivots; + bool drawMTBullishPivots; + bool drawMTBearishPivots; + bool drawOBBullishPivots; + bool drawOBBearishPivots; // // Styling ... @@ -96,6 +100,14 @@ class XCXCATBEAPOIDrawer : public XCBase XCATBPivotStyle peakPivotStyle; XCATBPivotStyle valePivotStyle; + // + XCATBPivotStyle mtBullishPivotStyle; + XCATBPivotStyle mtBearishPivotStyle; + + // + XCATBPivotStyle obBullishPivotStyle; + XCATBPivotStyle obBearishPivotStyle; + // // Constructors ... XCXCATBEAPOIDrawer( @@ -138,6 +150,10 @@ class XCXCATBEAPOIDrawer : public XCBase // Drawing ... drawPeakPivots = false; drawValePivots = false; + drawMTBullishPivots = false; + drawMTBearishPivots = false; + drawOBBullishPivots = false; + drawOBBearishPivots = false; // // Styling ... @@ -161,6 +177,16 @@ class XCXCATBEAPOIDrawer : public XCBase // PV ... peakPivotStyle = defaultBearishStyle; valePivotStyle = defaultBullishStyle; + + // + // MT ... + mtBullishPivotStyle = defaultBearishStyle; + mtBearishPivotStyle = defaultBullishStyle; + + // + // OB ... + obBullishPivotStyle = defaultBearishStyle; + obBearishPivotStyle = defaultBullishStyle; } // @@ -170,6 +196,16 @@ class XCXCATBEAPOIDrawer : public XCBase // PV ... DrawPeakPivots(to); DrawValePivots(to); + + // + // MT ... + DrawMTBullishPivots(to); + DrawMTBearishPivots(to); + + // + // OB ... + DrawOBBullishPivots(to); + DrawOBBearishPivots(to); } // @@ -226,7 +262,7 @@ class XCXCATBEAPOIDrawer : public XCBase switch (iType) { // - case XCA_PEAK: + case XCATB_PEAK: // DrawPeakPivot( box, @@ -235,13 +271,49 @@ class XCXCATBEAPOIDrawer : public XCBase break; // - case XCA_VALE: + case XCATB_VALE: // DrawValePivot( box, to // ); break; + + // + case XCATB_BULLISH_MT: + // + DrawMTBullishPivot( + box, + to // + ); + break; + + // + case XCATB_BEARISH_MT: + // + DrawMTBearishPivot( + box, + to // + ); + break; + + // + case XCATB_BULLISH_OB: + // + DrawOBBullishPivot( + box, + to // + ); + break; + + // + case XCATB_BEARISH_OB: + // + DrawOBBearishPivot( + box, + to // + ); + break; } } // @@ -370,12 +442,20 @@ class XCXCATBEAPOIDrawer : public XCBase // Cleanup Styles ... peakPivotStyle.Clean(); valePivotStyle.Clean(); + mtBullishPivotStyle.Clean(); + mtBearishPivotStyle.Clean(); + obBullishPivotStyle.Clean(); + obBearishPivotStyle.Clean(); // // Cleanup Pivot Objects Holder ... mObjects.Clear(); mPeakPivotObjects.Clear(); mValePivotObjects.Clear(); + mMTBullishPivotObjects.Clear(); + mMTBearishPivotObjects.Clear(); + mOBBullishPivotObjects.Clear(); + mOBBearishPivotObjects.Clear(); } // @@ -451,6 +531,146 @@ class XCXCATBEAPOIDrawer : public XCBase } } + // + void DrawMTBullishPivots(datetime to = NULL) + { + // + bool has = drawMTBullishPivots; + if (!has) + { + return; + } + + // + has = detector.HasMTBullishPivots(); + if (!has) + { + return; + } + + // + int count = detector.CountMTBullishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.mtBullishPivots[i]; + + // + DrawMTBullishPivot( + iBox, + to // + ); + + // + iBox.Clean(); + } + } + + // + void DrawMTBearishPivots(datetime to = NULL) + { + // + bool has = drawMTBearishPivots; + if (!has) + { + return; + } + + // + has = detector.HasMTBearishPivots(); + if (!has) + { + return; + } + + // + int count = detector.CountMTBearishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.mtBearishPivots[i]; + + // + DrawMTBearishPivot( + iBox, + to // + ); + + // + iBox.Clean(); + } + } + + // + void DrawOBBullishPivots(datetime to = NULL) + { + // + bool has = drawOBBullishPivots; + if (!has) + { + return; + } + + // + has = detector.HasOBBullishPivots(); + if (!has) + { + return; + } + + // + int count = detector.CountOBBullishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.obBullishPivots[i]; + + // + DrawOBBullishPivot( + iBox, + to // + ); + + // + iBox.Clean(); + } + } + + // + void DrawOBBearishPivots(datetime to = NULL) + { + // + bool has = drawOBBearishPivots; + if (!has) + { + return; + } + + // + has = detector.HasOBBearishPivots(); + if (!has) + { + return; + } + + // + int count = detector.CountOBBearishPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.obBearishPivots[i]; + + // + DrawOBBearishPivot( + iBox, + to // + ); + + // + iBox.Clean(); + } + } + // // One Item Drawers ... @@ -469,8 +689,8 @@ class XCXCATBEAPOIDrawer : public XCBase // has = item.IsValid() && - item.type == GetBoxType(XCA_PEAK) && - item.dir == GetDirection(XCA_PEAK); + item.type == GetBoxType(XCATB_PEAK) && + item.dir == GetDirection(XCATB_PEAK); if (!has) { return; @@ -522,8 +742,8 @@ class XCXCATBEAPOIDrawer : public XCBase // has = item.IsValid() && - item.type == GetBoxType(XCA_VALE) && - item.dir == GetDirection(XCA_VALE); + item.type == GetBoxType(XCATB_VALE) && + item.dir == GetDirection(XCATB_VALE); if (!has) { return; @@ -560,6 +780,218 @@ class XCXCATBEAPOIDrawer : public XCBase ZeroMemory(iObj); } + // + void DrawMTBullishPivot( + XBoxZone &item, + datetime to = NULL // + ) + { + // + bool has = drawMTBullishPivots; + if (!has) + { + return; + } + + // + has = item.IsValid() && + item.type == GetBoxType(XCATB_BULLISH_MT) && + item.dir == GetDirection(XCATB_BULLISH_MT); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + item.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + item, + iObj // + ); + if (has) + { + // + // Style Object ... + ApplyPivotStyle( + iObj, + mtBullishPivotStyle // + ); + + // + // Store Object ... + mMTBullishPivotObjects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + // + void DrawMTBearishPivot( + XBoxZone &item, + datetime to = NULL // + ) + { + // + bool has = drawMTBearishPivots; + if (!has) + { + return; + } + + // + has = item.IsValid() && + item.type == GetBoxType(XCATB_BEARISH_MT) && + item.dir == GetDirection(XCATB_BEARISH_MT); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + item.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + item, + iObj // + ); + if (has) + { + // + // Style Object ... + ApplyPivotStyle( + iObj, + mtBearishPivotStyle // + ); + + // + // Store Object ... + mMTBearishPivotObjects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + // + void DrawOBBullishPivot( + XBoxZone &item, + datetime to = NULL // + ) + { + // + bool has = drawOBBullishPivots; + if (!has) + { + return; + } + + // + has = item.IsValid() && + item.type == GetBoxType(XCATB_BULLISH_OB) && + item.dir == GetDirection(XCATB_BULLISH_OB); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + item.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + item, + iObj // + ); + if (has) + { + // + // Style Object ... + ApplyPivotStyle( + iObj, + obBullishPivotStyle // + ); + + // + // Store Object ... + mOBBullishPivotObjects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + // + void DrawOBBearishPivot( + XBoxZone &item, + datetime to = NULL // + ) + { + // + bool has = drawOBBearishPivots; + if (!has) + { + return; + } + + // + has = item.IsValid() && + item.type == GetBoxType(XCATB_BEARISH_OB) && + item.dir == GetDirection(XCATB_BEARISH_OB); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + item.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + item, + iObj // + ); + if (has) + { + // + // Style Object ... + ApplyPivotStyle( + iObj, + obBearishPivotStyle // + ); + + // + // Store Object ... + mOBBearishPivotObjects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + // // Protected ... protected: @@ -590,7 +1022,7 @@ class XCXCATBEAPOIDrawer : public XCBase // // Props ... XCXCATBEAPOIDetector *detector; - + // CArrayObj mObjects; @@ -598,6 +1030,14 @@ class XCXCATBEAPOIDrawer : public XCBase CArrayObj mPeakPivotObjects; CArrayObj mValePivotObjects; + // + CArrayObj mMTBullishPivotObjects; + CArrayObj mMTBearishPivotObjects; + + // + CArrayObj mOBBullishPivotObjects; + CArrayObj mOBBearishPivotObjects; + // }; diff --git a/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 b/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 index 90bdeb7c..84dd467b 100644 --- a/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 +++ b/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 @@ -78,6 +78,860 @@ string ToString(ENUM_XCATBEA_TRADE_FINALIZATION value) return result; } +// +// Position Selecting ... +enum ENUM_XCATBEA_POSITION_SELECT_TYPES +{ + XCATBEA_POSITION_SELECT_NONE = 0, // None + XCATBEA_POSITION_SELECT_ALL = 1, // All + XCATBEA_POSITION_SELECT_IN_PROFITS = 2, // In Profit Positions + XCATBEA_POSITION_SELECT_IN_DRAWDOWNS = 3, // In Drawdown Positions + XCATBEA_POSITION_SELECT_OLDEST = 4, // Oldest Position + XCATBEA_POSITION_SELECT_YOUNGEST = 5, // Youngest Position + XCATBEA_POSITION_SELECT_IN_PROFITS_OLDEST = 6, // In Profit Positions Oldest one + XCATBEA_POSITION_SELECT_IN_PROFITS_YOUNGEST = 7, // In Profit Positions Youngest one + XCATBEA_POSITION_SELECT_IN_PROFITS_MIN = 8, // Minimum Profitable Position + XCATBEA_POSITION_SELECT_IN_PROFITS_MAX = 9, // Maximum Profitable Position + XCATBEA_POSITION_SELECT_IN_DRAWDOWN_OLDEST = 10, // In Drawdown Positions Oldest one + XCATBEA_POSITION_SELECT_IN_DRAWDOWN_YOUNGEST = 11, // In Drawdown Positions Youngest one + XCATBEA_POSITION_SELECT_IN_DRAWDOWN_MIN = 12, // Minimum in Drawdown Position + XCATBEA_POSITION_SELECT_IN_DRAWDOWN_MAX = 13, // Maximum in Drawdown Position + XCATBEA_POSITION_SELECT_SAMES = 14, // Same Type Positions + XCATBEA_POSITION_SELECT_SAMES_OLDEST = 15, // Same Type Positions Oldest one + XCATBEA_POSITION_SELECT_SAMES_YOUNGEST = 16, // Same Type Positions Youngest one + XCATBEA_POSITION_SELECT_OPPOSITS = 17, // Opposit Type Positions + XCATBEA_POSITION_SELECT_OPPOSIT_OLDEST = 18, // Opposit Type Positions Oldest one + XCATBEA_POSITION_SELECT_OPPOSIT_YOUNGEST = 19, // Opposit Type Positions Youngest one + XCATBEA_POSITION_SELECT_SAME_IN_PROFITS = 20, // Same Type In Profit Positions + XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_OLDEST = 21, // Same Type In Profit Positions Oldest one + XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_YOUNGEST = 22, // Same Type In Profit Positions Youngest one + XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_MIN = 23, // Minimum Profitable of Same Type Positions + XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_MAX = 24, // Maximum Profitable of Same Type Positions + XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS = 25, // Opposit Type In Profit Positions + XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_OLDEST = 26, // Opposit Type In Profit Positions Oldest one + XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_YOUNGEST = 27, // Opposit Type In Profit Positions Youngest one + XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_MIN = 28, // Minimum Profitable of Opposit Type Positions + XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_MAX = 29, // Maximum Profitable of Opposit Type Positions + XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWNS = 30, // Same Type In Deawdown Positions + XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_OLDEST = 31, // Same Type In Deawdown Positions Oldest one + XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_YOUNGEST = 32, // Same Type In Deawdown Positions Youngest one + XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_MIN = 33, // Minimum In Drawdown of Same Type Positions + XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_MAX = 34, // Maximum In Drawdown of Same Type Positions + XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWNS = 35, // Opposit Type In Deawdown Positions + XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_OLDEST = 36, // Opposit Type In Deawdown Positions Oldest one + XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_YOUNGEST = 37, // Opposit Type In Deawdown Positions Youngest one + XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MIN = 38, // Minimum In Drawdown of Opposit Type Positions + XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MAX = 39, // Maximum In Drawdown of Opposit Type Positions +}; + +// +bool IsValid(ENUM_XCATBEA_POSITION_SELECT_TYPES value) +{ + return value != XCATBEA_POSITION_SELECT_NONE; +} + +// +string ToString(ENUM_XCATBEA_POSITION_SELECT_TYPES value) +{ + return EnumToString(value); +} + +/** + * Select Specified Position's Related Position(s) + * for Protecting ... + * + * @param selecteds: XPosition instance reference Collection, for Holding Selected Positions ... + * @param positions: XPosition instance reference Collection, All available source Positions ... + * @param forType: ENUM_X_POSITION_TYPES member, Spcified Position Type to Select for it ... + * @param selectType: ENUM_XCATBEA_POSITION_SELECT_TYPES member, Specified Positions Selecting Senario ... + * + * @return ( bool ) + */ +bool SelectPosition( + XPosition &selecteds[], + XPosition &positions[], + ENUM_X_POSITION_TYPES forType, + ENUM_XCATBEA_POSITION_SELECT_TYPES selectType // +) +{ + // + bool result = false; + + // + // Normalize Args ... + Clean(selecteds); + + // + // Validate Args ... + result = + IsValid(forType) && + HasChild(positions) && + IsValid(selectType); + if (!result) + { + return result; + } + + // + // Extract Separate Type of Positions ... + + // + int idx = -1; + bool has = false; + XPosition iPosition; + + // + bool isLong = IsLong(forType); + bool isShort = IsShort(forType); + int count = ArraySize(positions); + + // + XPosition samePositions[]; + XPosition oppositPositions[]; + XPosition inProfitPositions[]; + XPosition inDrawdownPositions[]; + XPosition sameInProfitPositions[]; + XPosition sameInDrawdownPositions[]; + XPosition oppositInProfitPositions[]; + XPosition oppositInDrawdownPositions[]; + + // + for (int i = 0; i < count; i++) + { + // + // Select Indexed Position ... + iPosition = positions[i]; + + // + bool isIPosLong = IsLong(iPosition.type); + bool isIPosShort = IsShort(iPosition.type); + + // + // Select if Same Type ... + bool isSame = + (isLong && isIPosLong) || + (isShort && isIPosShort); + if (isSame) + { + // + AddRef( + iPosition, + samePositions // + ); + } + + // + // Select if Opposit Type ... + bool isOpposit = + (isLong && isIPosShort) || + (isShort && isIPosLong); + if (isOpposit) + { + // + AddRef( + iPosition, + oppositPositions // + ); + } + + // + iPosition.Clean(); + } + + // + // Filling Other Requirement Collections ... + + // + ExtractInProfitPositions( + positions, + inProfitPositions // + ); + + // + ExtractInProfitPositions( + samePositions, + sameInProfitPositions // + ); + + // + ExtractInProfitPositions( + oppositPositions, + oppositInProfitPositions // + ); + + // + ExtractInDrawdownPositions( + positions, + inDrawdownPositions // + ); + + // + ExtractInDrawdownPositions( + samePositions, + sameInDrawdownPositions // + ); + + // + ExtractInDrawdownPositions( + oppositPositions, + oppositInDrawdownPositions // + ); + + // + // Implement Selection Senario ... + switch (selectType) + { + // + case XCATBEA_POSITION_SELECT_ALL: + // + Copy( + positions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_IN_PROFITS: + // + Copy( + inProfitPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_IN_DRAWDOWNS: + // + Copy( + inDrawdownPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_OLDEST: + // + GetOldest( + iPosition, + positions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_YOUNGEST: + // + GetYoungest( + iPosition, + positions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_PROFITS_OLDEST: + // + GetOldest( + iPosition, + inProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_PROFITS_YOUNGEST: + // + GetYoungest( + iPosition, + inProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_PROFITS_MIN: + // + idx = FindMinProfitIndex(inProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = inProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_PROFITS_MAX: + // + idx = FindMaxProfitIndex(inProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = inProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_DRAWDOWN_OLDEST: + // + GetOldest( + iPosition, + inDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_DRAWDOWN_YOUNGEST: + // + GetYoungest( + iPosition, + inDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_DRAWDOWN_MIN: + // + idx = FindMinDrawdownIndex(inDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = inDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_IN_DRAWDOWN_MAX: + // + idx = FindMaxDrawdownIndex(inDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = inDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAMES: + // + Copy( + samePositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_SAMES_OLDEST: + // + GetOldest( + iPosition, + samePositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAMES_YOUNGEST: + // + GetYoungest( + iPosition, + samePositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS: + // + Copy( + oppositPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_OLDEST: + // + GetOldest( + iPosition, + oppositPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_YOUNGEST: + // + GetYoungest( + iPosition, + oppositPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_PROFITS: + // + Copy( + sameInProfitPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_OLDEST: + // + GetOldest( + iPosition, + sameInProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_YOUNGEST: + // + GetYoungest( + iPosition, + sameInProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_MIN: + // + idx = FindMinProfitIndex(sameInProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = sameInProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_PROFITS_MAX: + // + idx = FindMaxProfitIndex(sameInProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = sameInProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS: + // + Copy( + oppositInProfitPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_OLDEST: + // + GetOldest( + iPosition, + oppositInProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_YOUNGEST: + // + GetYoungest( + iPosition, + oppositInProfitPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_MIN: + // + idx = FindMinProfitIndex(oppositInProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = oppositInProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSIT_IN_PROFITS_MAX: + // + idx = FindMaxProfitIndex(oppositInProfitPositions); + if (IsValidIndex(idx)) + { + // + iPosition = oppositInProfitPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWNS: + // + Copy( + sameInDrawdownPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_OLDEST: + // + GetOldest( + iPosition, + sameInDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_YOUNGEST: + // + GetYoungest( + iPosition, + sameInDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_MIN: + // + idx = FindMinDrawdownIndex(sameInDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = sameInDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_SAME_IN_DRAWDOWN_MAX: + // + idx = FindMaxDrawdownIndex(sameInDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = sameInDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWNS: + // + Copy( + oppositInDrawdownPositions, + selecteds // + ); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_OLDEST: + // + GetOldest( + iPosition, + oppositInDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_YOUNGEST: + // + GetYoungest( + iPosition, + oppositInDrawdownPositions // + ); + if (iPosition.IsValid()) + { + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MIN: + // + idx = FindMinDrawdownIndex(oppositInDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = oppositInDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + case XCATBEA_POSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MAX: + // + idx = FindMaxDrawdownIndex(oppositInDrawdownPositions); + if (IsValidIndex(idx)) + { + // + iPosition = oppositInDrawdownPositions[idx]; + + // + AddRef( + iPosition, + selecteds // + ); + } + iPosition.Clean(); + break; + + // + } + + // + // Validate Result ... + result = HasChild(selecteds); + + // + // Cleanup Resources ... + + // + if (!result) + { + Clean(selecteds); + } + + // + Clean(samePositions); + Clean(oppositPositions); + Clean(inProfitPositions); + Clean(inDrawdownPositions); + Clean(sameInProfitPositions); + Clean(sameInDrawdownPositions); + Clean(oppositInProfitPositions); + Clean(oppositInDrawdownPositions); + + // + return result; +} + // struct XCATBEASymbolInfo { diff --git a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 index 928cd78d..c4aa12ee 100644 --- a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 +++ b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 @@ -25,6 +25,8 @@ #include "../../Libraries/x-saherelm.common.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" #include "../../Libraries/x-saherelm.x-trade.lib.mq5" +#include "../Classes/xcatbea.x-poi.detector.class.mq5" +#include "../Classes/xcatbea.x-poi.drawer.class.mq5" #include "../Libraries/xcatbea.lib.mq5" // @@ -350,7 +352,11 @@ bool ToSignal( * @return ( bool ) */ bool DetectSignalZone( + XBoxZone &peak, + XBoxZone &vale, XCX121XCatbHelper *helper, + XCXCATBEAPOIDrawer *drawer, + XCXCATBEAPOIDetector *detector, XCBarAnalyser *barAnalyser, X121XCatbConditions &conditions, XBoxZone &signalZone, @@ -371,13 +377,725 @@ bool DetectSignalZone( // // Validate Args ... result = + peak.IsValid() && + vale.IsValid() && helper != NULL && + detector != NULL && barAnalyser != NULL; if (!result) { return result; } + // + // Try to Recieve Conditions of Market ... + + // + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + XBoxZone iOB; + XBoxZone iMT; + int idx = -1; + bool has = false; + bool isBullish = false; + bool isBearish = false; + double bullishScore = 0; + double bearishScore = 0; + + // + double iUpper = 0; + double iLower = 0; + string iType = NULL; + datetime iTo = NULL; + string iSymbol = NULL; + datetime iFrom = NULL; + ENUM_TIMEFRAMES iPeriod = NULL; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Signalling ... + if (result) + { + // + iSymbol = conditions.symbol; + iPeriod = conditions.period; + + // + // Looking For Conditions ... + + // + // Reading Values ... + + // + // Readng Scores ... + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + // Prepared Conditions ... + + // + // SCORES ... + bool isScoreBullish = bullishScore > bearishScore; + bool isScoreBearish = bearishScore > bullishScore; + + // + // 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 + // + ) + // + ; + + // + // 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; + + // + // Implement Signalling Conditions ... + + // + // -------------- + // Conditions 1: + // -------------- + // Descriptions: + // using Parabolic Sar Trending Start Conditions + // then attached others .. + // ---------------------------------- + + // + bool isCond1Bullish = + // + // Start ... + (isSarBullishStart && + !isSarBearishStart) && + // + // SCORE ... + isScoreBullish && + // + // BAR ... + isBarBullishPressured && + // + // KI ... + // conditions.isKIUp && + conditions.isKIBullish && + // + // ATR ... + conditions.isATRUp && + // + // TREND ... + conditions.isTrendUp // && + // conditions.isTrendBullish + // + ; + + // + bool isCond1Bearish = + // + // Start ... + (isSarBearishStart && + !isSarBullishStart) && + // + // SCORE ... + isScoreBearish && + // + // BAR ... + isBarBearishPressured && + // + // KI ... + // conditions.isKIDown && + conditions.isKIBearish && + // + // ATR ... + conditions.isATRDown && + // + // TREND ... + conditions.isTrendDown // && + // conditions.isTrendBearish + // + ; + + // + bool isCond1 = + isCond1Bullish || + isCond1Bearish; + if (isCond1) + { + // + // Validate Some Other Requirements ... + + // + // We Have to Detect Youngest Order Block ... + // or Mitigation Block ... + if (isCond1Bullish) + { + // + // OB ... + idx = GetYoungest(detector.obBullishPivots); + has = IsValidIndex(idx); + if (has) + { + iOB = detector.obBullishPivots[idx]; + } + + // + // MT ... + idx = GetYoungest(detector.mtBullishPivots); + has = IsValidIndex(idx); + if (has) + { + iOB = detector.mtBullishPivots[idx]; + } + } + else if (isCond1Bearish) + { + // + // OB + idx = GetYoungest(detector.obBearishPivots); + has = IsValidIndex(idx); + if (has) + { + iOB = detector.obBearishPivots[idx]; + } + + // + // MT + idx = GetYoungest(detector.mtBearishPivots); + has = IsValidIndex(idx); + if (has) + { + iMT = detector.mtBearishPivots[idx]; + } + } + + // + // Now we can Do some Verifications Using these ... + + // + // All Requirements based on Cond 1 ... + } + // ---------------------------------- + + // + // Summarizing Result ... + + // + isBullish = + // + isCond1Bullish + // + ; + + // + isBearish = + // + isCond1Bearish + // + ; + } + + // + result = + isBullish || + isBearish; + + // + // Preparing Signal Zone ... + if (result) + { + // + iDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Preparing Signal Zone ... + signalZone.to = iTo; + signalZone.dir = iDir; + signalZone.from = iFrom; + signalZone.type = iType; + signalZone.upper = iUpper; + signalZone.lower = iLower; + signalZone.symbol = iSymbol; + signalZone.period = iPeriod; + + // + // Temparory Object ... + color iColor = + isBullish + ? clrAqua + : clrMagenta; + string iName = "Conditions_" + ToString(iDir) + "_" + ToString(((int)conditions.time)); + + // + CChartObjectVLine *iObj = new CChartObjectVLine(); + has = iObj.Create( + 0, + iName, + 0, + conditions.bars[zIDX].time // + ); + if (has) + { + // + iObj.Color(iColor); + } + + // + // Validate Signal Zone and Draw it ... + has = signalZone.IsValid(); + if (has) + { + drawer.DrawBox(signalZone); + } + + // + // Draw MT and OB if Exists ... + if (iOB.IsValid()) + { + // + drawer.DrawBox( + iOB, + conditions.bars[zIDX].time, + false, // Draw Middle ... + true // Ignore Type ... + ); + } + if (iMT.IsValid()) + { + // + drawer.DrawBox( + iMT, + conditions.bars[zIDX].time, + false, // Draw Middle ... + true // Ignore Type ... + ); + } + + // + Print("Conditions ..."); + } + // // Validate Result ... result = signalZone.IsValid(); @@ -385,6 +1103,10 @@ bool DetectSignalZone( // // Cleanup Resources ... + // + iOB.Clean(); + iMT.Clean(); + // if (!result) {