last works ...
This commit is contained in:
@@ -0,0 +1,504 @@
|
||||
### 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). 🎯
|
||||
Reference in New Issue
Block a user