adding provided strategy 1 signalling conditions ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -533,13 +533,13 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Signaller Flags ...
|
// Signaller Flags ...
|
||||||
bool useSignaller1 = false;
|
bool useSignaller1 = true;
|
||||||
bool useSignaller2 = false;
|
bool useSignaller2 = false;
|
||||||
bool useSignaller3 = false;
|
bool useSignaller3 = false;
|
||||||
bool useSignaller4 = false;
|
bool useSignaller4 = false;
|
||||||
bool useSignaller5 = false;
|
bool useSignaller5 = false;
|
||||||
bool useSignaller6 = false;
|
bool useSignaller6 = false;
|
||||||
bool useSignaller7 = true;
|
bool useSignaller7 = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
XBoxZone tmpZone;
|
XBoxZone tmpZone;
|
||||||
@@ -975,9 +975,14 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #region Custom Signal Strategies ...
|
// #region Custom Signal Strategies ...
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| X121XKI Strategy 1: POI + KI Confluence |
|
||||||
|
//| Concept: Order Block/FVG + KI Trend Confirmation |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check Bar Has Signal Based on Strategy 1 ...
|
* Check Bar Has Signal Based on Strategy 1 ...
|
||||||
* POI ...
|
* POI + KI Confluence ...
|
||||||
*
|
*
|
||||||
* @param bar: XOHCL, reference to Bar ...
|
* @param bar: XOHCL, reference to Bar ...
|
||||||
* @param zone: XBoxZone, reference to holds affected zone ...
|
* @param zone: XBoxZone, reference to holds affected zone ...
|
||||||
@@ -1002,359 +1007,669 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
|
|||||||
dir = X_DIRECTION_NONE;
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
//
|
//
|
||||||
result = bar.IsValid();
|
result = bar.IsValid() &&
|
||||||
|
kiParser.IsValid();
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Configuration ...
|
||||||
double score = 0;
|
double score = 0;
|
||||||
bool isBullish = false;
|
bool isBullish = false;
|
||||||
bool isBearish = false;
|
bool isBearish = false;
|
||||||
int barIndex = bar.Index() + 1;
|
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
|
||||||
|
int kiConfirmationBars = 3; // Bars for KI confirmation
|
||||||
|
|
||||||
|
// #region KI Trend Confirmation ...
|
||||||
|
//
|
||||||
|
// Check KI Fast Trend ...
|
||||||
|
bool kiFastBullish = kiParser.IsKIFastBullish(barIndex);
|
||||||
|
bool kiFastBearish = kiParser.IsKIFastBearish(barIndex);
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEST ...
|
// Check KI Slow Trend ...
|
||||||
|
bool kiSlowBullish = kiParser.IsKISlowBullish(barIndex);
|
||||||
|
bool kiSlowBearish = kiParser.IsKISlowBearish(barIndex);
|
||||||
|
|
||||||
//
|
//
|
||||||
if (kiParser.IsKIFastBullish(barIndex))
|
// Check KI Super Slow Trend ...
|
||||||
|
bool kiSuperSlowBullish = kiParser.IsKISlowBullish(barIndex);
|
||||||
|
bool kiSuperSlowBearish = kiParser.IsKISlowBearish(barIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool kiWaveBullish = kiParser.IsKIWaveSwitchedToBullish(barIndex);
|
||||||
|
bool kiWaveBearish = kiParser.IsKIWaveSwitchedToBearish(barIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool priceAboveKIFast = bar.close > kiHelper.GetKIFast(barIndex);
|
||||||
|
bool priceBelowKIFast = bar.close < kiHelper.GetKIFast(barIndex);
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region RSI Momentum Confirmation ...
|
||||||
|
//
|
||||||
|
// Check RSI State ...
|
||||||
|
bool rsiBullish = kiParser.IsRSISwitchedToBullish(barIndex, 55, 2);
|
||||||
|
bool rsiBearish = kiParser.IsRSISwitchedToBearish(barIndex, 45, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check RSI Overbought/Oversold ...
|
||||||
|
bool rsiOverbought = kiParser.IsRSIOverbought(barIndex, 70, 2);
|
||||||
|
bool rsiOversold = kiParser.IsRSIOversold(barIndex, 30, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check RSI Divergence (Price vs RSI) ...
|
||||||
|
bool rsiBullishDivergence = false;
|
||||||
|
bool rsiBearishDivergence = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple Divergence Check (can be enhanced) ...
|
||||||
|
if (barIndex + 5 < bar.TotalBars())
|
||||||
{
|
{
|
||||||
DebugBreak();
|
//
|
||||||
|
double currentRSI = kiHelper.GetRSI(barIndex);
|
||||||
|
double previousRSI = kiHelper.GetRSI(barIndex + 5);
|
||||||
|
double currentLow = bar.low;
|
||||||
|
double previousLow = bar.FindLowest(5, MODE_LOW);
|
||||||
|
double currentHigh = bar.high;
|
||||||
|
double previousHigh = bar.FindHighest(5, MODE_HIGH);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Divergence ...
|
||||||
|
rsiBullishDivergence = (currentLow < previousLow) && (currentRSI > previousRSI);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Divergence ...
|
||||||
|
rsiBearishDivergence = (currentHigh > previousHigh) && (currentRSI < previousRSI);
|
||||||
}
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
// //
|
// #region ATR Volatility Check ...
|
||||||
// bool hasTrend =
|
//
|
||||||
// kiParser.HasCompositeTrend(
|
// Check Volatility Expansion ...
|
||||||
// score,
|
bool volatilityHigh = kiParser.IsVolatilityHigh(barIndex);
|
||||||
// dir,
|
bool volatilitySwitchedHigh = kiParser.IsVolatilitySwitchdToHigh(barIndex);
|
||||||
// barIndex,
|
|
||||||
// 20, // Required Score ...
|
|
||||||
// 2, // Tolerance ...
|
|
||||||
// X_PRICE_CLOSE,
|
|
||||||
// 55,
|
|
||||||
// 45,
|
|
||||||
// 70,
|
|
||||||
// 30 //
|
|
||||||
// );
|
|
||||||
// if (hasTrend && IsXBearish(dir))
|
|
||||||
// {
|
|
||||||
// DebugBreak();
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return false;
|
// Check ATR Breakout ...
|
||||||
|
bool atrBreakoutUp = kiParser.IsATRBreakoutUp(barIndex, X_PRICE_CLOSE);
|
||||||
|
bool atrBreakoutDown = kiParser.IsATRBreakoutDown(barIndex, X_PRICE_CLOSE);
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region POI Detection (Order Blocks & FVG) ...
|
||||||
|
//
|
||||||
|
// Detect Order Blocks ...
|
||||||
|
XBoxZone bullishOBs[];
|
||||||
|
XBoxZone bearishOBs[];
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize Indexed Bar ...
|
int bullishOBCount = poiDetector.CollectOBs(bar, bullishOBs, 5, 10, 100);
|
||||||
XOHCL iBar;
|
int bearishOBCount = poiDetector.CollectOBs(bar, bearishOBs, 5, 10, 100);
|
||||||
result = iBar.Init(bar.symbol, bar.period, barIndex);
|
|
||||||
if (!result)
|
//
|
||||||
|
// 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++)
|
||||||
{
|
{
|
||||||
return result;
|
//
|
||||||
|
double obRange = (bullishOBs[i].upper - bullishOBs[i].lower) / points;
|
||||||
|
if (obRange >= minOBPoints && !IsXValid(bullishOBs[i].breakAt))
|
||||||
|
{
|
||||||
|
AddIfNotExists(bullishOBs[i], validBullishOBs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
XBoxZone swingLow;
|
// 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))
|
||||||
|
{
|
||||||
|
AddIfNotExists(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))
|
||||||
|
{
|
||||||
|
AddIfNotExists(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))
|
||||||
|
{
|
||||||
|
AddIfNotExists(bearishFVGs[i], validBearishFVGs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Liquidity Check ...
|
||||||
|
//
|
||||||
|
// Detect Recent Swings (Liquidity Pools) ...
|
||||||
XBoxZone swingHigh;
|
XBoxZone swingHigh;
|
||||||
ENUM_X_DIRECTION patternsDir[];
|
XBoxZone swingLow;
|
||||||
ENUM_X_BAR_PATTERN patterns[];
|
|
||||||
poiDetector.FillStrategy1Patterns(
|
|
||||||
patterns,
|
|
||||||
patternsDir //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reading Swings ...
|
poiDetector.DetectRecentSwings(swingHigh, swingLow, barIndex, 50, 500, period, true);
|
||||||
poiDetector.DetectRecentSwings(
|
|
||||||
swingHigh,
|
|
||||||
swingLow,
|
|
||||||
barIndex //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reading Order Flow ...
|
// Check if Liquidity was Swept ...
|
||||||
|
bool liquiditySweptHigh = false;
|
||||||
|
bool liquiditySweptLow = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bullish Order Flow ...
|
if (swingHigh.IsValid())
|
||||||
XBoxZone bullishOrderFlow[];
|
|
||||||
int bullishOrderFlowRejectdIDX = -1;
|
|
||||||
poiDetector.HasOrderFlow(bullishOrderFlow, barIndex, 4, X_DIRECTION_BULLISH, 15);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Bearish Order Flow ...
|
|
||||||
XBoxZone bearishOrderFlow[];
|
|
||||||
int bearishOrderFlowRejectdIDX = -1;
|
|
||||||
poiDetector.HasOrderFlow(bearishOrderFlow, barIndex, 4, X_DIRECTION_BEARISH, 15);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Base Conditions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
isBullish =
|
|
||||||
IsTFBullishPattern(barIndex, PERIOD_M1) &&
|
|
||||||
IsTFBullishPattern(barIndex, PERIOD_M5) &&
|
|
||||||
IsTFBullishPattern(barIndex, iBar.period) &&
|
|
||||||
HasRejected(
|
|
||||||
bullishOrderFlowRejectdIDX,
|
|
||||||
iBar,
|
|
||||||
bullishOrderFlow //
|
|
||||||
) &&
|
|
||||||
poiDetector.HasRecentPatternRejected(
|
|
||||||
zone,
|
|
||||||
patterns,
|
|
||||||
patternsDir,
|
|
||||||
barIndex,
|
|
||||||
3, // Loopback ..
|
|
||||||
iBar.period,
|
|
||||||
X_DIRECTION_BULLISH //
|
|
||||||
);
|
|
||||||
if (!isBullish)
|
|
||||||
{
|
{
|
||||||
//
|
liquiditySweptHigh = bar.high > swingHigh.upper;
|
||||||
isBearish =
|
|
||||||
IsTFBearishPattern(barIndex, PERIOD_M1) &&
|
|
||||||
IsTFBearishPattern(barIndex, PERIOD_M5) &&
|
|
||||||
IsTFBearishPattern(barIndex, iBar.period) &&
|
|
||||||
HasRejected(
|
|
||||||
bearishOrderFlowRejectdIDX,
|
|
||||||
iBar,
|
|
||||||
bearishOrderFlow //
|
|
||||||
) &&
|
|
||||||
poiDetector.HasRecentPatternRejected(
|
|
||||||
zone,
|
|
||||||
patterns,
|
|
||||||
patternsDir,
|
|
||||||
barIndex,
|
|
||||||
3, // Loopback ..
|
|
||||||
iBar.period,
|
|
||||||
X_DIRECTION_BEARISH //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Summarize Result ...
|
if (swingLow.IsValid())
|
||||||
result = isBullish || isBearish;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Count Touches ...
|
|
||||||
// int bullishTouches = 0;
|
|
||||||
// int bearishTouches = 0;
|
|
||||||
// if (result)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// kiParser.CountTouches(
|
|
||||||
// bullishTouches,
|
|
||||||
// bearishTouches,
|
|
||||||
// barIndex,
|
|
||||||
// 4 // Loopback ...
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// isBullish =
|
|
||||||
// isBullish &&
|
|
||||||
// bullishTouches >= bearishTouches;
|
|
||||||
|
|
||||||
// //
|
|
||||||
// isBearish =
|
|
||||||
// isBearish &&
|
|
||||||
// bearishTouches >= bullishTouches;
|
|
||||||
|
|
||||||
// //
|
|
||||||
// // Summarize Result ...
|
|
||||||
// result = isBullish || isBearish;
|
|
||||||
// if (!result)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// isBullish = false;
|
|
||||||
// isBearish = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (bullishTouches > 0 || bearishTouches > 0)
|
|
||||||
// {
|
|
||||||
// // DebugBreak();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
|
||||||
if (!result)
|
|
||||||
{
|
{
|
||||||
|
liquiditySweptLow = bar.low < swingLow.lower;
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Multi-Timeframe Confirmation ...
|
||||||
//
|
//
|
||||||
iBar.Clean();
|
// Check Lower Timeframe Alignment ...
|
||||||
|
bool isLowerTFBullish = IsTFBullishPattern(barIndex, PERIOD_M1);
|
||||||
|
bool isLowerTFBearish = IsTFBearishPattern(barIndex, PERIOD_M1);
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
// Check Higher Timeframe Alignment ...
|
||||||
|
bool isHigherTFBullish = IsTFBullishPattern(barIndex, GetNearestPeriod(period));
|
||||||
|
bool isHigherTFBearish = IsTFBearishPattern(barIndex, GetNearestPeriod(period));
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// #region Bullish Signal Logic ...
|
||||||
|
//
|
||||||
|
// Calculate Bullish Score ...
|
||||||
|
double bullishScore = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI Trend Alignment (Max 5 points) ...
|
||||||
|
if (kiFastBullish)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kiSlowBullish)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Do Directional Validation ...
|
// HTF bias more important
|
||||||
if (result)
|
if (kiSuperSlowBullish)
|
||||||
{
|
{
|
||||||
//
|
bullishScore += 2;
|
||||||
poiDetector.RefactorStrategy1OperationalZone(zone);
|
}
|
||||||
|
|
||||||
//
|
if (priceAboveKIFast)
|
||||||
// Bullish ...
|
|
||||||
if (isBullish)
|
|
||||||
{
|
{
|
||||||
// //
|
bullishScore += 1;
|
||||||
// isBullish =
|
|
||||||
// isBullish &&
|
|
||||||
// isLowerTFBullish &&
|
|
||||||
// isCandlestickBullish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bearish ...
|
// KI Wave Momentum (Max 2 points) ...
|
||||||
if (isBearish)
|
if (kiWaveBullish)
|
||||||
{
|
{
|
||||||
// //
|
bullishScore += 2;
|
||||||
// isBearish =
|
|
||||||
// isBearish &&
|
|
||||||
// isLowerTFBearish &&
|
|
||||||
// isCandlestickBearish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
result = isBullish || isBearish;
|
// RSI Confirmation (Max 3 points) ...
|
||||||
if (!result)
|
if (rsiBullish)
|
||||||
{
|
{
|
||||||
|
bullishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Divergence is strong signal ...
|
||||||
|
if (rsiBullishDivergence)
|
||||||
|
{
|
||||||
|
bullishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsiOversold)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Volatility (Max 2 points) ...
|
||||||
|
if (volatilityHigh)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volatilitySwitchedHigh)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// POI Presence (Max 5 points) ...
|
||||||
|
if (ArraySize(validBullishOBs) > 0)
|
||||||
|
{
|
||||||
|
bullishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArraySize(validBullishFVGs) > 0)
|
||||||
|
{
|
||||||
|
bullishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Liquidity Sweep (Max 3 points) ...
|
||||||
|
if (liquiditySweptLow)
|
||||||
|
{
|
||||||
|
bullishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MTF Alignment (Max 2 points) ...
|
||||||
|
if (isLowerTFBullish)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHigherTFBullish)
|
||||||
|
{
|
||||||
|
bullishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bullish Conditions ...
|
||||||
|
isBullish = (bullishScore >= minScore) &&
|
||||||
|
(ArraySize(validBullishOBs) > 0 ||
|
||||||
|
ArraySize(validBullishFVGs) > 0) &&
|
||||||
|
(kiFastBullish || kiWaveBullish);
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Bearish Signal Logic ...
|
||||||
|
//
|
||||||
|
// Calculate Bearish Score ...
|
||||||
|
double bearishScore = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI Trend Alignment (Max 5 points) ...
|
||||||
|
if (kiFastBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kiSlowBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kiSuperSlowBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priceBelowKIFast)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI Wave Momentum (Max 2 points) ...
|
||||||
|
if (kiWaveBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI Confirmation (Max 3 points) ...
|
||||||
|
if (rsiBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsiBearishDivergence)
|
||||||
|
{
|
||||||
|
bearishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsiOverbought)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Volatility (Max 2 points) ...
|
||||||
|
if (volatilityHigh)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volatilitySwitchedHigh)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// POI Presence (Max 5 points) ...
|
||||||
|
if (ArraySize(validBearishOBs) > 0)
|
||||||
|
{
|
||||||
|
bearishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArraySize(validBearishFVGs) > 0)
|
||||||
|
{
|
||||||
|
bearishScore += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Liquidity Sweep (Max 3 points) ...
|
||||||
|
if (liquiditySweptHigh)
|
||||||
|
{
|
||||||
|
bearishScore += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MTF Alignment (Max 2 points) ...
|
||||||
|
if (isLowerTFBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHigherTFBearish)
|
||||||
|
{
|
||||||
|
bearishScore += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bearish Conditions ...
|
||||||
|
isBearish = (bearishScore >= minScore) &&
|
||||||
|
(ArraySize(validBearishOBs) > 0 ||
|
||||||
|
ArraySize(validBearishFVGs) > 0) &&
|
||||||
|
(kiFastBearish || kiWaveBearish);
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Signal Generation ...
|
||||||
|
//
|
||||||
|
// Ensure Only One Direction ...
|
||||||
|
if (isBullish && isBearish)
|
||||||
|
{
|
||||||
|
// Use higher score to determine direction ...
|
||||||
|
if (bullishScore > bearishScore)
|
||||||
|
{
|
||||||
|
isBearish = false;
|
||||||
|
}
|
||||||
|
else if (bearishScore > bullishScore)
|
||||||
|
{
|
||||||
|
isBullish = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Same score, no signal ...
|
||||||
isBullish = false;
|
isBullish = false;
|
||||||
isBearish = false;
|
isBearish = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Draws ...
|
// Generate Bullish Signal ...
|
||||||
bool draw = true;
|
if (isBullish)
|
||||||
if (draw && result)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
int drawn = 0;
|
dir = X_DIRECTION_BULLISH;
|
||||||
|
|
||||||
//
|
//
|
||||||
poiDrawer.drawnObjects.Clear();
|
// Select Best POI (Youngest Valid OB or FVG) ...
|
||||||
|
XBoxZone selectedPOI;
|
||||||
|
|
||||||
//
|
//
|
||||||
XPOIDrawConfig config;
|
int obIdx = GetYoungest(validBullishOBs);
|
||||||
config.Default();
|
int fvgIdx = GetYoungest(validBullishFVGs);
|
||||||
|
|
||||||
//
|
//
|
||||||
if (zone.IsValid())
|
if (IsValidIndex(obIdx) && IsValidIndex(fvgIdx))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
drawn++;
|
// Choose the one closer to current price ...
|
||||||
|
double obDistance = bar.close - validBullishOBs[obIdx].upper;
|
||||||
|
double fvgDistance = bar.close - validBullishFVGs[fvgIdx].upper;
|
||||||
|
|
||||||
//
|
//
|
||||||
config.zonesWidth = 3;
|
selectedPOI = (obDistance < fvgDistance) ? validBullishOBs[obIdx] : validBullishFVGs[fvgIdx];
|
||||||
config.bullishColor = clrYellow;
|
}
|
||||||
config.bearishColor = clrOrange;
|
else if (IsValidIndex(obIdx))
|
||||||
|
{
|
||||||
//
|
selectedPOI = validBullishOBs[obIdx];
|
||||||
poiDrawer.DrawZone(zone, config);
|
}
|
||||||
|
else if (IsValidIndex(fvgIdx))
|
||||||
//
|
{
|
||||||
config.Default();
|
selectedPOI = validBullishFVGs[fvgIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (swingLow.IsValid())
|
// Validate Selected POI ...
|
||||||
|
if (selectedPOI.IsValid())
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
drawn++;
|
zone = selectedPOI;
|
||||||
poiDrawer.DrawZone(swingLow, config);
|
zone.type = "S1_POI_KI";
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Calculate Targets ...
|
||||||
|
double entry = GetEntry(symbol, dir);
|
||||||
|
double risk = MathAbs(entry - zone.lower);
|
||||||
|
double reward = risk * defaultSignalR2R;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP1: 1:1 R:R ...
|
||||||
|
XTarget tp1;
|
||||||
|
tp1.target = entry + risk;
|
||||||
|
tp1.volumeMultiplier = 0.5;
|
||||||
|
tp1.doRF = true;
|
||||||
|
tp1.doRFOnEntry = false;
|
||||||
|
AddRef(tp1, targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP2: 1:2 R:R ...
|
||||||
|
XTarget tp2;
|
||||||
|
tp2.target = entry + (risk * 2);
|
||||||
|
tp2.volumeMultiplier = 0.5;
|
||||||
|
tp2.doRF = false;
|
||||||
|
tp2.doRFOnEntry = false;
|
||||||
|
AddRef(tp2, targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP3: Next Liquidity (Swing High) ...
|
||||||
if (swingHigh.IsValid())
|
if (swingHigh.IsValid())
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
drawn++;
|
XTarget tp3;
|
||||||
poiDrawer.DrawZone(swingHigh, config);
|
tp3.target = swingHigh.upper + (10 * points);
|
||||||
|
tp3.volumeMultiplier = 1.0;
|
||||||
|
tp3.doRF = false;
|
||||||
|
tp3.doRFOnEntry = false;
|
||||||
|
AddRef(tp3, targets);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (HasChild(bullishOrderFlow))
|
// Generate Bearish Signal ...
|
||||||
|
else if (isBearish)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
drawn += ArraySize(bullishOrderFlow);
|
dir = X_DIRECTION_BEARISH;
|
||||||
poiDrawer.DrawZones(bullishOrderFlow, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
if (HasChild(bearishOrderFlow))
|
// Select Best POI (Youngest Valid OB or FVG) ...
|
||||||
|
XBoxZone selectedPOI;
|
||||||
|
|
||||||
|
//
|
||||||
|
int obIdx = GetYoungest(validBearishOBs);
|
||||||
|
int fvgIdx = GetYoungest(validBearishFVGs);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValidIndex(obIdx) && IsValidIndex(fvgIdx))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
drawn += ArraySize(bearishOrderFlow);
|
// Choose the one closer to current price ...
|
||||||
poiDrawer.DrawZones(bearishOrderFlow, config);
|
double obDistance = zone.lower - bar.close;
|
||||||
}
|
double fvgDistance = zone.lower - bar.close;
|
||||||
|
|
||||||
//
|
//
|
||||||
if (drawn > 0)
|
selectedPOI = (obDistance < fvgDistance) ? validBearishOBs[obIdx] : validBearishFVGs[fvgIdx];
|
||||||
|
}
|
||||||
|
else if (IsValidIndex(obIdx))
|
||||||
{
|
{
|
||||||
DebugBreak();
|
selectedPOI = validBearishOBs[obIdx];
|
||||||
return false;
|
}
|
||||||
|
else if (IsValidIndex(fvgIdx))
|
||||||
|
{
|
||||||
|
selectedPOI = validBearishFVGs[fvgIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
config.Clean();
|
// Validate Selected POI ...
|
||||||
|
if (selectedPOI.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zone = selectedPOI;
|
||||||
|
zone.type = "S1_POI_KI";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Targets ...
|
||||||
|
double entry = GetEntry(symbol, dir);
|
||||||
|
double risk = MathAbs(zone.upper - entry);
|
||||||
|
double reward = risk * defaultSignalR2R;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP1: 1:1 R:R ...
|
||||||
|
XTarget tp1;
|
||||||
|
tp1.target = entry - risk;
|
||||||
|
tp1.volumeMultiplier = 0.5;
|
||||||
|
tp1.doRF = true;
|
||||||
|
tp1.doRFOnEntry = false;
|
||||||
|
AddRef(tp1, targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP2: 1:2 R:R ...
|
||||||
|
XTarget tp2;
|
||||||
|
tp2.target = entry - (risk * 2);
|
||||||
|
tp2.volumeMultiplier = 0.5;
|
||||||
|
tp2.doRF = false;
|
||||||
|
tp2.doRFOnEntry = false;
|
||||||
|
AddRef(tp2, targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP3: Next Liquidity (Swing Low) ...
|
||||||
|
if (swingLow.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XTarget tp3;
|
||||||
|
tp3.target = swingLow.lower - (10 * points);
|
||||||
|
tp3.volumeMultiplier = 1.0;
|
||||||
|
tp3.doRF = false;
|
||||||
|
tp3.doRFOnEntry = false;
|
||||||
|
AddRef(tp3, targets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check and Prepare Direction ...
|
if (riskInPoints > maxAllowedRiskDistance)
|
||||||
dir =
|
{
|
||||||
isBullish
|
//
|
||||||
? X_DIRECTION_BULLISH
|
result = false;
|
||||||
: isBearish ? X_DIRECTION_BEARISH
|
zone.Clean();
|
||||||
: X_DIRECTION_NONE;
|
XClean(targets);
|
||||||
result = result &&
|
dir = X_DIRECTION_NONE;
|
||||||
HasDirection(dir);
|
}
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optional: Debug Break for Testing ...
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Prepare Zone ...
|
Print("Strategy 1 Signal Detected:");
|
||||||
double entry = GetEntry(iBar.symbol, dir);
|
Print(" Direction: ", ToXString(dir));
|
||||||
|
Print(" Bullish Score: ", bullishScore);
|
||||||
//
|
Print(" Bearish Score: ", bearishScore);
|
||||||
double upper = isBullish
|
Print(" POI Type: ", zone.type);
|
||||||
? entry
|
Print(" Targets Count: ", ArraySize(targets));
|
||||||
: zone.upper;
|
DebugBreak();
|
||||||
double lower = isBullish
|
|
||||||
? zone.lower
|
|
||||||
: entry;
|
|
||||||
datetime to = bar.time;
|
|
||||||
datetime from = isBullish
|
|
||||||
? zone.from
|
|
||||||
: zone.from;
|
|
||||||
result = zone.Init(
|
|
||||||
iBar.symbol,
|
|
||||||
iBar.period,
|
|
||||||
upper,
|
|
||||||
lower,
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
dir,
|
|
||||||
"XS1" //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cleanup Resources ...
|
// Cleanup Resources ...
|
||||||
iBar.Clean();
|
XClean(bullishOBs);
|
||||||
swingLow.Clean();
|
XClean(bearishOBs);
|
||||||
XClean(patterns);
|
XClean(bullishFVGs);
|
||||||
swingHigh.Clean();
|
XClean(bearishFVGs);
|
||||||
XClean(patternsDir);
|
XClean(validBullishOBs);
|
||||||
XClean(bullishOrderFlow);
|
XClean(validBearishOBs);
|
||||||
XClean(bearishOrderFlow);
|
XClean(validBullishFVGs);
|
||||||
|
XClean(validBearishFVGs);
|
||||||
//
|
|
||||||
result =
|
|
||||||
result &&
|
|
||||||
zone.IsValid() &&
|
|
||||||
HasDirection(dir);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user