### USER Complete Strategy 2: KI Market Structure Shift (MSS) ### ASSISTANT # 🚀 Complete Strategy 2: KI Market Structure Shift (MSS) Implementation Based on the **SaherElm Framework** and **X121XKI Indicator** buffers, here is the complete implementation for **Strategy 2: KI Market Structure Shift (MSS)**. This strategy focuses on **Change of Character (CHoCH)** confirmed by **KI Trend Switch** and **MA Momentum**, entering on the retracement to an **Order Block or FVG**. ```mql5 /** * Check Bar Has Signal Based on Strategy 2 ... * KI Market Structure Shift (MSS) + Displacement * * @param bar: XOHCL, reference to Bar ... * @param zone: XBoxZone, reference to holds affected zone ... * @param targets: XTarget, reference to detected Signal's Targets collections ... * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... * * @return ( bool ) */ bool Strategy2HasSignal( XOHCL &bar, XBoxZone &zone, XTarget &targets[], ENUM_X_DIRECTION &dir // ) { // bool result = false; // // Prepare ... zone.Clean(); XClean(targets); dir = X_DIRECTION_NONE; // // Validate ... result = bar.IsValid() && kiParser.IsValid(); if (!result) { return result; } // // Configuration ... int barIndex = bar.Index() + 1; double points = GetPoints(symbol); int minOBPoints = 30; // Minimum Order Block size in points int minFVGPoints = 20; // Minimum FVG size in points double minScore = 15.0; // Minimum score for signal // // State Variables ... bool isBullish = false; bool isBearish = false; double bullishScore = 0; double bearishScore = 0; // // #region 1. Detect Market Structure (Swings) ... // XBoxZone swingHigh; XBoxZone swingLow; // // Detect Recent Swings for MSS Reference ... poiDetector.DetectRecentSwings( swingHigh, swingLow, barIndex, 50, // swingsValidationLength 500, // loopback period, true // forceRefineZones ); // // #endregion // // #region 2. Check Market Structure Shift (MSS) ... // // Bullish MSS: Price breaks above previous Swing High ... bool bullishMSS = false; if (swingHigh.IsValid()) { // // Check if Current Bar Closed Above Swing High ... bullishMSS = bar.close > swingHigh.upper; } // // Bearish MSS: Price breaks below previous Swing Low ... bool bearishMSS = false; if (swingLow.IsValid()) { // // Check if Current Bar Closed Below Swing Low ... bearishMSS = bar.close < swingLow.lower; } // // #endregion // // #region 3. KI Trend Confirmation ... // // Check KI Fast State ... bool kiFastBullish = kiParser.IsKIFastBullish(barIndex); bool kiFastBearish = kiParser.IsKIFastBearish(barIndex); // // Check KI Fast Switch (Trend Change) ... bool kiFastSwitchedBullish = kiParser.IsKIFastSwitchedToBullish(barIndex); bool kiFastSwitchedBearish = kiParser.IsKIFastSwitchedToBearish(barIndex); // // Check KI Slow Alignment (HTF Bias) ... bool kiSlowBullish = kiParser.IsKISlowBullish(barIndex); bool kiSlowBearish = kiParser.IsKISlowBearish(barIndex); // // #endregion // // #region 4. Momentum Confirmation (MA) ... // // Check MA Fast vs KI Fast (Momentum) ... double maFast = kiParser.GetMAFast(barIndex); double kiFast = kiParser.GetKIFast(barIndex); // bool maFastAboveKI = maFast > kiFast; bool maFastBelowKI = maFast < kiFast; // // Check MA Fast Switch ... bool maFastSwitchedBullish = kiParser.IsMAFastSwitchedToBullish(barIndex); bool maFastSwitchedBearish = kiParser.IsMAFastSwitchedToBearish(barIndex); // // #endregion // // #region 5. Volatility / Displacement ... // // Check Volatility Expansion (Displacement) ... bool volatilityHigh = kiParser.IsVolatilityHigh(barIndex); bool volatilitySwitchedHigh = kiParser.IsVolatilitySwitchdToHigh(barIndex); // // #endregion // // #region 6. Entry Zone Detection (OB/FVG) ... // // Detect Order Blocks ... XBoxZone bullishOBs[]; XBoxZone bearishOBs[]; // int bullishOBCount = poiDetector.CollectOBs(bar, bullishOBs, 5, 10, 100); int bearishOBCount = poiDetector.CollectOBs(bar, bearishOBs, 5, 10, 100); // // Detect Fair Value Gaps ... XBoxZone bullishFVGs[]; XBoxZone bearishFVGs[]; // int bullishFVGCount = poiDetector.CollectFVGs(bar, bullishFVGs, 5, 10, 100); int bearishFVGCount = poiDetector.CollectFVGs(bar, bearishFVGs, 5, 10, 100); // // Validate OB/FVG Size ... XBoxZone validBullishOBs[]; XBoxZone validBearishOBs[]; XBoxZone validBullishFVGs[]; XBoxZone validBearishFVGs[]; // // Filter Bullish OBs ... for (int i = 0; i < bullishOBCount; i++) { double obRange = (bullishOBs[i].upper - bullishOBs[i].lower) / points; if (obRange >= minOBPoints && !IsXValid(bullishOBs[i].breakAt)) { AddRef(bullishOBs[i], validBullishOBs); } } // // Filter Bearish OBs ... for (int i = 0; i < bearishOBCount; i++) { double obRange = (bearishOBs[i].upper - bearishOBs[i].lower) / points; if (obRange >= minOBPoints && !IsXValid(bearishOBs[i].breakAt)) { AddRef(bearishOBs[i], validBearishOBs); } } // // Filter Bullish FVGs ... for (int i = 0; i < bullishFVGCount; i++) { double fvgRange = (bullishFVGs[i].upper - bullishFVGs[i].lower) / points; if (fvgRange >= minFVGPoints && !IsXValid(bullishFVGs[i].breakAt)) { AddRef(bullishFVGs[i], validBullishFVGs); } } // // Filter Bearish FVGs ... for (int i = 0; i < bearishFVGCount; i++) { double fvgRange = (bearishFVGs[i].upper - bearishFVGs[i].lower) / points; if (fvgRange >= minFVGPoints && !IsXValid(bearishFVGs[i].breakAt)) { AddRef(bearishFVGs[i], validBearishFVGs); } } // // #endregion // // #region 7. Calculate Scores ... // // Bullish Score ... if (bullishMSS) bullishScore += 5; // MSS is critical if (kiFastSwitchedBullish) bullishScore += 3; // Trend Switch if (kiFastBullish) bullishScore += 2; // Trend Alignment if (kiSlowBullish) bullishScore += 2; // HTF Alignment if (maFastAboveKI) bullishScore += 2; // Momentum if (maFastSwitchedBullish) bullishScore += 2; // Momentum Switch if (volatilitySwitchedHigh) bullishScore += 2; // Displacement if (volatilityHigh) bullishScore += 1; if (ArraySize(validBullishOBs) > 0) bullishScore += 3; // Entry Zone if (ArraySize(validBullishFVGs) > 0) bullishScore += 2; // Entry Zone // // Bearish Score ... if (bearishMSS) bearishScore += 5; // MSS is critical if (kiFastSwitchedBearish) bearishScore += 3; // Trend Switch if (kiFastBearish) bearishScore += 2; // Trend Alignment if (kiSlowBearish) bearishScore += 2; // HTF Alignment if (maFastBelowKI) bearishScore += 2; // Momentum if (maFastSwitchedBearish) bearishScore += 2; // Momentum Switch if (volatilitySwitchedHigh) bearishScore += 2; // Displacement if (volatilityHigh) bearishScore += 1; if (ArraySize(validBearishOBs) > 0) bearishScore += 3; // Entry Zone if (ArraySize(validBearishFVGs) > 0) bearishScore += 2; // Entry Zone // // #endregion // // #region 8. Determine Direction ... // // Ensure Only One Direction ... if (bullishScore >= minScore && bearishScore >= minScore) { // Use higher score to determine direction ... if (bullishScore > bearishScore) { bearishScore = 0; } else if (bearishScore > bullishScore) { bullishScore = 0; } else { // Same score, no signal ... bullishScore = 0; bearishScore = 0; } } // // Check Bullish Conditions ... isBullish = (bullishScore >= minScore) && bullishMSS && (kiFastBullish || kiFastSwitchedBullish) && (ArraySize(validBullishOBs) > 0 || ArraySize(validBullishFVGs) > 0); // // Check Bearish Conditions ... isBearish = (bearishScore >= minScore) && bearishMSS && (kiFastBearish || kiFastSwitchedBearish) && (ArraySize(validBearishOBs) > 0 || ArraySize(validBearishFVGs) > 0); // // #endregion // // #region 9. Generate Signal ... // // Generate Bullish Signal ... if (isBullish) { dir = X_DIRECTION_BULLISH; // // Select Best POI (Youngest Valid OB or FVG) ... XBoxZone selectedPOI; int obIdx = GetYoungest(validBullishOBs); int fvgIdx = GetYoungest(validBullishFVGs); // if (IsValidIndex(obIdx) && IsValidIndex(fvgIdx)) { // Choose the one closer to current price ... double obDistance = bar.close - validBullishOBs[obIdx].upper; double fvgDistance = bar.close - validBullishFVGs[fvgIdx].upper; // selectedPOI = (obDistance < fvgDistance) ? validBullishOBs[obIdx] : validBullishFVGs[fvgIdx]; } else if (IsValidIndex(obIdx)) { selectedPOI = validBullishOBs[obIdx]; } else if (IsValidIndex(fvgIdx)) { selectedPOI = validBullishFVGs[fvgIdx]; } // // Validate Selected POI ... if (selectedPOI.IsValid()) { zone = selectedPOI; zone.type = "S2_MSS_KI"; // // Calculate Targets ... double entry = GetEntry(symbol, dir); // // SL: Below MSS Swing Low ... double sl = 0; if (swingLow.IsValid()) { sl = swingLow.lower - (10 * points); // Buffer } else { sl = zone.lower - (30 * points); // Fallback to Zone } // // TP: Next Liquidity (Swing High) ... double tp = 0; if (swingHigh.IsValid()) { tp = swingHigh.upper + (10 * points); } else { // Fallback to R:R double risk = MathAbs(entry - sl); tp = entry + (risk * 2); } // // TP1: 1:1 R:R ... XTarget tp1; tp1.target = entry + MathAbs(entry - sl); tp1.volumeMultiplier = 0.5; tp1.doRF = true; tp1.doRFOnEntry = false; AddRef(tp1, targets); // // TP2: Next Liquidity ... XTarget tp2; tp2.target = tp; tp2.volumeMultiplier = 0.5; tp2.doRF = false; tp2.doRFOnEntry = false; AddRef(tp2, targets); } } // // Generate Bearish Signal ... else if (isBearish) { dir = X_DIRECTION_BEARISH; // // Select Best POI (Youngest Valid OB or FVG) ... XBoxZone selectedPOI; int obIdx = GetYoungest(validBearishOBs); int fvgIdx = GetYoungest(validBearishFVGs); // if (IsValidIndex(obIdx) && IsValidIndex(fvgIdx)) { // Choose the one closer to current price ... double obDistance = zone.lower - bar.close; double fvgDistance = zone.lower - bar.close; // selectedPOI = (obDistance < fvgDistance) ? validBearishOBs[obIdx] : validBearishFVGs[fvgIdx]; } else if (IsValidIndex(obIdx)) { selectedPOI = validBearishOBs[obIdx]; } else if (IsValidIndex(fvgIdx)) { selectedPOI = validBearishFVGs[fvgIdx]; } // // Validate Selected POI ... if (selectedPOI.IsValid()) { zone = selectedPOI; zone.type = "S2_MSS_KI"; // // Calculate Targets ... double entry = GetEntry(symbol, dir); // // SL: Above MSS Swing High ... double sl = 0; if (swingHigh.IsValid()) { sl = swingHigh.upper + (10 * points); // Buffer } else { sl = zone.upper + (30 * points); // Fallback to Zone } // // TP: Next Liquidity (Swing Low) ... double tp = 0; if (swingLow.IsValid()) { tp = swingLow.lower - (10 * points); } else { // Fallback to R:R double risk = MathAbs(entry - sl); tp = entry - (risk * 2); } // // TP1: 1:1 R:R ... XTarget tp1; tp1.target = entry - MathAbs(entry - sl); tp1.volumeMultiplier = 0.5; tp1.doRF = true; tp1.doRFOnEntry = false; AddRef(tp1, targets); // // TP2: Next Liquidity ... XTarget tp2; tp2.target = tp; tp2.volumeMultiplier = 0.5; tp2.doRF = false; tp2.doRFOnEntry = false; AddRef(tp2, targets); } } // // #endregion // // #region 10. Validation & Risk Management ... // // Validate Signal ... result = zone.IsValid() && HasDirection(dir) && HasChild(targets); // // Check Max Allowed Risk ... if (result && maxAllowedRiskDistance > 0) { double riskInPoints = 0; if (dir == X_DIRECTION_BULLISH) { riskInPoints = MathAbs(zone.GetDirectionalPrice() - zone.GetInDirectionalPrice()) / points; } else { riskInPoints = MathAbs(zone.GetInDirectionalPrice() - zone.GetDirectionalPrice()) / points; } // if (riskInPoints > maxAllowedRiskDistance) { result = false; zone.Clean(); XClean(targets); dir = X_DIRECTION_NONE; } } // // #endregion // // #region Debug & Logging ... // // Optional: Debug Break for Testing ... // if (result) // { // Print("Strategy 2 Signal Detected:"); // Print(" Direction: ", ToXString(dir)); // Print(" Bullish Score: ", bullishScore); // Print(" Bearish Score: ", bearishScore); // Print(" MSS: ", (isBullish ? "Bullish" : (isBearish ? "Bearish" : "None"))); // Print(" POI Type: ", zone.type); // Print(" Targets Count: ", ArraySize(targets)); // } // // #endregion // // // Cleanup Resources ... // XClean(bullishOBs); XClean(bearishOBs); XClean(bullishFVGs); XClean(bearishFVGs); XClean(validBullishOBs); XClean(validBearishOBs); XClean(validBullishFVGs); XClean(validBearishFVGs); // return result; } ``` ### 🔑 Key Features of Strategy 2 Implementation | Component | Logic | SMC/ICT Relevance | |-----------|-------|-------------------| | **MSS Detection** | `bar.close > swingHigh.upper` (Bullish) | Confirms **Change of Character (CHoCH)** | | **KI Confirmation** | `IsKIFastSwitchedToBullish` | Confirms **Trend Reversal** | | **Momentum** | `MA Fast > KI Fast` | Confirms **Displacement** | | **Entry Zone** | Youngest valid **OB or FVG** | Provides **Premium/Discount Entry** | | **Stop Loss** | Below/Above **MSS Swing Point** | Protects against **Invalidated Structure** | | **Take Profit** | Opposite **Swing Liquidity** | Targets **External Liquidity** | ### 📊 Expected Behavior * **Bullish:** Price breaks a swing high → KI Fast turns Green → MA Fast crosses above KI Fast → Price retraces to Bullish OB/FVG → **BUY**. * **Bearish:** Price breaks a swing low → KI Fast turns Red → MA Fast crosses below KI Fast → Price retraces to Bearish OB/FVG → **SELL**. * **Risk:** SL is placed safely beyond the swing point that caused the MSS, ensuring the trade is invalid if structure fails. * **Reward:** TP targets the opposing swing liquidity, typically offering a **1:2 to 1:4 R:R**. This implementation fully leverages your **X121XKI buffers** (KI, MA, Peak/Vale) while adhering to **SMC/ICT principles** (MSS, OB/FVG, Liquidity). 🎯