Files
MQL5Data/X121XKIEA/Documents/Strategies/Strategy 2 - KI Market Structure Shift (MSS).md
T
2026-02-27 01:46:11 +03:30

13 KiB

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.

/**
* 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). 🎯