This commit is contained in:
2026-01-06 02:20:25 +03:30
parent 2df090d2f3
commit fb03a1c88a
5 changed files with 1467 additions and 28 deletions
+20 -1
View File
@@ -8,7 +8,17 @@
{
"id": "61ca33e6-05e4-4b44-b88d-3bc8ae5cba86",
"title": "To Do",
"cards": []
"cards": [
{
"id": "a59a73f4-1ab4-477b-893e-b2dfb71fe6ea",
"listId": "61ca33e6-05e4-4b44-b88d-3bc8ae5cba86",
"title": "Add Support for PV in XKI Indicator.",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
}
]
},
{
"id": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
@@ -38,6 +48,15 @@
}
],
"comments": []
},
{
"id": "bad677c0-a119-4f44-be8b-185fc4c996c7",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "add Targets in strategy 1",
"description": "use Guards Instead of Targets.",
"labels": [],
"checkboxes": [],
"comments": []
}
]
},
+162
View File
@@ -318,6 +318,101 @@ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[])
return ArraySize(dest);
}
/**
* Get All Available Valid Bar Patterns ...
*
* @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill Patterns ...
* @param dir: ENUM_X_DIRECTION, collection reference to Fill Directions ...
* @param forDir: ENUM_X_DIRECTION, Force Patterns Direction ...
*
* @return ( int )
*/
int GetAllBarPatters(
ENUM_X_BAR_PATTERN &dest[],
ENUM_X_DIRECTION &dir[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
XClean(dest);
XClean(dir);
//
Add(X_BAR_PATTERN_HIGH, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_LOW, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_MOMENTUM, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_ENGULFED, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_TRUE_GAPED, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_PINNED, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_STAR, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_PIERCING, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_RISING, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_FLAG, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_SIGNALKEY, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_OB, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_FVG, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_SUPPORT, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_RESISTANCE, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_PULLBACK, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_CONSOLIDATION, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_LEG, dest);
Add(forDir, dir);
//
return ArraySize(dest);
}
/**
* Fill Required Candlestick Patters ...
*
@@ -352,6 +447,73 @@ int GetCandlestickPatterns(ENUM_X_BAR_PATTERN &dest[])
return result;
}
/**
* Fill Required Candlestick Patters ...
*
* @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill Patterns ...
* @param dir: ENUM_X_DIRECTION, collection reference to Fill Directions ...
* @param forDir: ENUM_X_DIRECTION, Force Patterns Direction ...
*
* @return ( int )
*/
int GetCandlestickPatterns(
ENUM_X_BAR_PATTERN &dest[],
ENUM_X_DIRECTION &dir[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
XClean(dir);
//
Add(X_BAR_PATTERN_STAR, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_FLAG, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_PINNED, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_RISING, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_MOMENTUM, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_ENGULFED, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_PIERCING, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_SIGNALKEY, dest);
Add(forDir, dir);
//
Add(X_BAR_PATTERN_TRUE_GAPED, dest);
Add(forDir, dir);
//
result = ArraySize(dest);
//
return result;
}
//
// Structures ...
+621
View File
@@ -0,0 +1,621 @@
/**
* Check Bar Has Signal Based on Strategy 1 ...
* POI ...
*
* @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 Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int scoreBullish = 0;
int scoreBearish = 0;
bool isBullish = false;
bool isBearish = false;
int barIndex = bar.Index() + 1;
//
// Initialize Indexed Bar ...
XOHCL iBar;
result = iBar.Init(bar.symbol, bar.period, barIndex);
if (!result)
{
return result;
}
// #region Reading Conditions and Scoring ...
//
// ATR ...
bool isATRUp = kiParser.IsVolatilityHigh(barIndex) ||
kiParser.IsVolatilitySwitchdToHigh(barIndex);
// #region KI ...
//
bool isKIReadyForBullish = ((kiParser.IsKIFastBearish(barIndex) ||
(kiParser.IsKIFastBullish(barIndex) &&
iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BULLISH))) &&
kiParser.IsKISlowBullish(barIndex));
//
bool isKIReadyForBearish = ((kiParser.IsKIFastBullish(barIndex) ||
(kiParser.IsKIFastBearish(barIndex) &&
iBar.IsRejected(kiHelper.GetKIFast(barIndex), X_DIRECTION_BEARISH))) &&
kiParser.IsKISlowBearish(barIndex));
//
bool isKIBandBullish = (kiHelper.GetKIUpper(barIndex) > kiHelper.GetKIUpper(barIndex + 1) ||
kiHelper.GetKILower(barIndex) > kiHelper.GetKILower(barIndex + 1));
//
bool isKIBandBearish = (kiHelper.GetKIUpper(barIndex) < kiHelper.GetKIUpper(barIndex + 1) ||
kiHelper.GetKILower(barIndex) < kiHelper.GetKILower(barIndex + 1));
//
bool isKIBullish = (kiParser.IsKIFastBullish(barIndex) ||
kiParser.IsKIFastSwitchedToBullish(barIndex)) &&
(kiParser.IsKISlowBullish(barIndex) ||
kiParser.IsKISlowSwitchedToBullish(barIndex));
if (isKIBullish)
{
scoreBullish++;
}
//
bool isKIBearish = (kiParser.IsKIFastBearish(barIndex) ||
kiParser.IsKIFastSwitchedToBearish(barIndex)) &&
(kiParser.IsKISlowBearish(barIndex) ||
kiParser.IsKISlowSwitchedToBearish(barIndex));
if (isKIBearish)
{
scoreBearish++;
}
// #endregion
// #region KI Wave ...
//
bool isKIWaveBullish = kiParser.IsKIWaveBullish(barIndex) ||
kiParser.IsKIWaveSwitchedToBullish(barIndex);
if (isKIWaveBullish)
{
scoreBullish++;
}
//
bool isKIWaveBearish = kiParser.IsKIWaveBearish(barIndex) ||
kiParser.IsKIWaveSwitchedToBearish(barIndex);
if (isKIWaveBearish)
{
scoreBearish++;
}
// #endregion
// #region MA ...
//
bool isMaBullish = kiParser.IsMACrossoverBullish(barIndex) ||
kiParser.IsMACrossoverSwitchedToBullish(barIndex);
if (isMaBullish)
{
scoreBullish++;
}
//
bool isMaBearish = kiParser.IsMACrossoverBearish(barIndex) ||
kiParser.IsMACrossoverSwitchedToBearish(barIndex);
if (isMaBearish)
{
scoreBearish++;
}
// #endregion
// #region LowerTF Candlstick ...
//
bool isLowerTFBullish = IsTFBullishPattern(barIndex, PERIOD_M5);
if (isLowerTFBullish)
{
scoreBullish++;
}
//
bool isLowerTFBearish = IsTFBearishPattern(barIndex, PERIOD_M5);
if (isLowerTFBearish)
{
scoreBearish++;
}
// #endregion
// #region Candlestick ...
//
bool isCandlestickBullish = poiDetector.HasCandlestickDirection(
iBar,
X_DIRECTION_BULLISH //
);
if (isCandlestickBullish)
{
scoreBullish++;
}
//
bool isCandlestickBearish = poiDetector.HasCandlestickDirection(
iBar,
X_DIRECTION_BEARISH //
);
if (isCandlestickBearish)
{
scoreBearish++;
}
// #endregion
// #endregion
// #region Summarize Directional Conditions ...
//
isBullish =
isATRUp &&
isLowerTFBullish &&
isKIReadyForBullish &&
isCandlestickBullish &&
scoreBullish >= 2 &&
(isKIBullish ||
isMaBullish ||
isKIWaveBullish ||
isKIBandBullish);
//
isBearish =
isATRUp &&
isLowerTFBearish &&
isKIReadyForBearish &&
isCandlestickBearish &&
scoreBearish >= 2 &&
(isKIBearish ||
isMaBearish ||
isKIWaveBearish ||
isKIBandBearish);
// #endregion
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
//
iBar.Clean();
//
return result;
}
//
// Select Operational Zone ...
if (isBullish)
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BULLISH);
}
else if (isBearish)
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BEARISH);
}
//
// Refactor Result ...
result = result &&
zone.IsValid();
if (result)
{
//
// Refine Zone ...
poiDetector.RefineZone(zone);
//
// SL Refactoring ...
//
XOHCL toBar;
if (zone.ToBar(toBar))
{
//
int to = zone.ToIndex();
int from = zone.FromIndex();
int length = from - to;
double iValue =
isBullish
? toBar.FindLowest(length, MODE_LOW)
: isBearish
? toBar.FindHighest(length, MODE_HIGH)
: EMPTY_VALUE;
if (NotEmptyZero(iValue))
{
//
if (isBullish)
{
zone.lower = MathMin(zone.lower, iValue);
}
//
if (isBearish)
{
zone.upper = MathMax(zone.upper, iValue);
}
}
}
toBar.Clean();
}
//
// Do Directional Validation ...
if (result)
{
//
// Bullish ...
if (isBullish)
{
//
isBullish =
isBullish &&
isLowerTFBullish &&
isCandlestickBullish;
}
//
// Bearish ...
if (isBearish)
{
//
isBearish =
isBearish &&
isLowerTFBearish &&
isCandlestickBearish;
}
//
result = isBullish || isBearish;
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// Validate Result ...
if (!result)
{
//
iBar.Clean();
//
return result;
}
//
// Draws ...
bool draw = true;
if (draw && result)
{
//
int drawn = 0;
//
XPOIDrawConfig config;
config.Default();
//
if (zone.IsValid())
{
//
drawn++;
//
config.zonesWidth = 3;
config.bullishColor = clrYellow;
config.bearishColor = clrOrange;
//
poiDrawer.DrawZone(zone, config);
//
config.Default();
}
//
config.Clean();
//
if (drawn > 0)
{
// DebugBreak();
}
}
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = result &&
HasDirection(dir);
if (!result)
{
//
iBar.Clean();
//
return result;
}
//
// Prepare Zone ...
double entry = GetEntry(iBar.symbol, dir);
if (result)
{
//
double upper = isBullish
? entry
: zone.upper;
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 ...
iBar.Clean();
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
bool HasRecentPatternTouched(
XBoxZone &zone,
double price,
int barIndex = 0,
int loopback = 5,
int threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result = NotEmptyZero(price);
if (!result)
{
return result;
}
//
// Normalize ...
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
bool has = false;
int iBullishIDX = -1;
int iBearishIDX = -1;
bool isBullish = false;
bool isBearish = false;
XBoxZone iBullishZones[];
XBoxZone iBearishZones[];
XPatternAnalysis iAnalysis;
XPatternAnalysisConfig iConfig;
//
// Preparing Pattern Analysis Config ...
iConfig.Default();
//
// Customize Patterns ...
// iConfig.FullPattern();
//
// iConfig.AddPattern(X_BAR_PATTERN_OB);
// iConfig.AddPattern(X_BAR_PATTERN_PINNED);
// iConfig.AddPattern(X_BAR_PATTERN_ENGULFED);
// iConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY);
//
// iConfig.AddPattern(X_BAR_PATTERN_FVG);
// iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// iConfig.AddPattern(X_BAR_PATTERN_STAR);
// iConfig.AddPattern(X_BAR_PATTERN_RISING);
// iConfig.AddPattern(X_BAR_PATTERN_MOMENTUM);
// iConfig.AddPattern(X_BAR_PATTERN_CONSOLIDATION);
// iConfig.AddPattern(X_BAR_PATTERN_LOW, X_DIRECTION_BULLISH);
// iConfig.AddPattern(X_BAR_PATTERN_HIGH, X_DIRECTION_BEARISH);
// iConfig.AddPattern(X_BAR_PATTERN_SUPPORT);
// iConfig.AddPattern(X_BAR_PATTERN_RESISTANCE);
//
// XAUUSD ...
iConfig.AddPattern(X_BAR_PATTERN_FVG);
iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// Looping Back ...
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
// Initialize Bar ...
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Analyse Patterns ...
has = AnalyseBarPatterns(iBar, iAnalysis, iConfig);
if (!has)
{
//
iBar.Clean();
continue;
}
//
// Bullish ...
has = iAnalysis.Count(X_DIRECTION_BULLISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBullishZones, X_DIRECTION_BULLISH);
has = HasChild(iBullishZones);
if (has)
{
//
has = HasNearZone(
iBullishIDX,
price,
threshold,
iBullishZones //
);
if (has)
{
isBullish = true;
}
}
}
//
// Bearish ...
has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH);
has = HasChild(iBearishZones);
if (has)
{
//
has = HasNearZone(
iBearishIDX,
price,
threshold,
iBearishZones //
);
if (has)
{
isBearish = true;
}
}
}
//
// Summarizing Result ...
has =
HasDirection(forDir)
? (isBullish && !isBearish && IsXBullish(forDir)) ||
(isBearish && !isBullish && IsXBearish(forDir))
: (isBullish && !isBearish) || (isBearish && !isBullish);
if (has)
{
//
// Fill Zones ...
if (isBullish)
{
zone = iBullishZones[iBullishIDX];
}
else
{
zone = iBearishZones[iBearishIDX];
}
break;
}
//
// Cleanup Resource ...
iBar.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
}
//
// Cleanup Resources ...
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
return result;
}
//
// XAUUSD ...
// //
// // FVG ...
// Add(X_BAR_PATTERN_FVG, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
// //
// // Piercing ...
// Add(X_BAR_PATTERN_PIERCING, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
@@ -988,6 +988,29 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
return result;
}
// #region Swings/OrderFlow ...
//
// Swings ...
XBoxZone swingLow;
XBoxZone swingHigh;
bool hasSwings = poiDetector.DetectRecentSwings(
swingHigh,
swingLow,
barIndex //
);
//
// Order Flow ...
//
XBoxZone bullishOrderFlow[];
result = poiDetector.HasOrderFlow(bullishOrderFlow, barIndex, 4, X_DIRECTION_BULLISH, 15);
//
XBoxZone bearishOrderFlow[];
result = poiDetector.HasOrderFlow(bearishOrderFlow, barIndex, 4, X_DIRECTION_BEARISH, 15);
// #endregion
// #region Reading Conditions and Scoring ...
//
// ATR ...
@@ -1150,24 +1173,96 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
}
//
if (result)
{
// DebugBreak();
}
// Select Operational Zone ...
ENUM_X_DIRECTION patternsDir[];
ENUM_X_BAR_PATTERN patterns[];
//
// Select Operational Zone ...
GetAllBarPatters(patterns, patternsDir);
//
// XAUUSD ...
// //
// // FVG ...
// Add(X_BAR_PATTERN_FVG, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
// //
// // Piercing ...
// Add(X_BAR_PATTERN_PIERCING, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
//
// EURUSD ...
//
// Add(X_BAR_PATTERN_STAR, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
// //
// Add(X_BAR_PATTERN_SUPPORT, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
// //
// Add(X_BAR_PATTERN_RESISTANCE, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
//
// Add(X_BAR_PATTERN_SIGNALKEY, patterns);
// Add(X_DIRECTION_NONE, patternsDir);
//
int nearestOrderFlowIDX = -1;
if (isBullish)
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BULLISH);
isBullish =
isBullish &&
HasChild(bullishOrderFlow) &&
poiDetector.HasNearZone(
nearestOrderFlowIDX,
iBar.close,
5,
bullishOrderFlow //
) &&
poiDetector.HasRecentPatternTouched(
zone,
patterns,
patternsDir,
iBar.close,
barIndex,
5,
5,
iBar.period,
X_DIRECTION_BULLISH //
);
}
else if (isBearish)
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BEARISH);
isBearish =
isBearish &&
HasChild(bearishOrderFlow) &&
poiDetector.HasNearZone(
nearestOrderFlowIDX,
iBar.close,
5,
bearishOrderFlow //
) &&
poiDetector.HasRecentPatternTouched(
zone,
patterns,
patternsDir,
iBar.close,
barIndex,
5,
5,
iBar.period,
X_DIRECTION_BEARISH //
);
}
//
@@ -1293,13 +1388,45 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
}
//
config.Clean();
if (swingLow.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(swingLow, config);
}
//
if (swingHigh.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(swingHigh, config);
}
//
if (HasChild(bullishOrderFlow))
{
//
drawn += ArraySize(bullishOrderFlow);
poiDrawer.DrawZones(bullishOrderFlow, config);
}
//
if (HasChild(bearishOrderFlow))
{
//
drawn += ArraySize(bearishOrderFlow);
poiDrawer.DrawZones(bearishOrderFlow, config);
}
//
if (drawn > 0)
{
// DebugBreak();
}
//
config.Clean();
}
//
@@ -1311,20 +1438,12 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
: X_DIRECTION_NONE;
result = result &&
HasDirection(dir);
if (!result)
{
//
iBar.Clean();
//
return result;
}
//
// Prepare Zone ...
double entry = GetEntry(iBar.symbol, dir);
if (result)
{
//
// Prepare Zone ...
double entry = GetEntry(iBar.symbol, dir);
//
double upper = isBullish
? entry
@@ -1348,12 +1467,15 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
);
}
// #region Preparing Target ...
// #endregion
//
// Cleanup Resources ...
iBar.Clean();
swingLow.Clean();
XClean(patterns);
swingHigh.Clean();
XClean(patternsDir);
XClean(bullishOrderFlow);
XClean(bearishOrderFlow);
//
result =
@@ -1371,7 +1493,8 @@ class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
*
* @return ( bool )
*/
bool Strategy2HasSignal(
bool
Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
@@ -1863,6 +1863,64 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
XClean(tmpResistances);
}
bool HasStructure(
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forMinorPeriod = NULL,
ENUM_TIMEFRAMES forMajorPeriod = NULL,
int loopback = 50,
int minorValidation = 7,
int majorValidation = 14,
int minimumRetests = 2,
double retestThreshold = 10,
int retestLoopback = 100 //
)
{
//
XBoxZone supports[];
XBoxZone resistances[];
XBoxZone minorSupport;
XBoxZone majorSupport;
XBoxZone minorResistance;
XBoxZone majorResistance;
//
GetCurrentStructure(
supports,
resistances,
minorSupport,
majorSupport,
minorResistance,
majorResistance,
barIndex,
forSymbol,
forMinorPeriod,
forMajorPeriod,
loopback,
minorValidation,
majorValidation,
minimumRetests,
retestThreshold,
retestLoopback //
);
//
bool result =
majorSupport.IsValid() &&
majorResistance.IsValid();
//
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
return result;
}
void RefineStructure(
XBoxZone &supports[],
XBoxZone &resistances[],
@@ -2164,6 +2222,427 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
zone.from = zone.breakAt;
}
}
bool DetectRecentSwings(
XBoxZone &swingHigh,
XBoxZone &swingLow,
int barIndex = 0,
int swingsValidationLength = 50,
int loopback = 500,
ENUM_TIMEFRAMES forPeriod = NULL,
bool forceRefineZones = true //
)
{
//
swingLow.Clean();
swingHigh.Clean();
//
loopback = NormalizeInt(loopback, 5);
barIndex = kiParser.NormalizeBarIndex(barIndex);
swingsValidationLength = NormalizeInt(swingsValidationLength, 5);
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
int iIDX = -1;
double low = 0;
double high = 0;
int lowIDX = -1;
int highIDX = -1;
bool has = false;
double iValue = 0;
datetime lowAt = NULL;
datetime highAt = NULL;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
iIDX = iBar.FindLowestIndex(swingsValidationLength, MODE_LOW);
has = IsValidIndex(iIDX);
if (has)
{
//
iValue = iLow(iBar.symbol, iBar.period, iIDX);
//
// Check Can Set Low ...
has = (!NotEmptyZero(low) ||
(NotEmptyZero(low) && iValue < low)) &&
IsValidSwing(
iValue,
iIDX,
barIndex,
iBar.symbol,
iBar.period,
X_SWING_LOW //
);
if (has)
{
//
low = iValue;
lowIDX = iIDX;
lowAt = iBar.time;
}
}
//
iIDX = iBar.FindHighestIndex(swingsValidationLength, MODE_HIGH);
has = IsValidIndex(iIDX);
if (has)
{
//
iValue = iHigh(iBar.symbol, iBar.period, iIDX);
//
// Check Can Set High ...
has = (!NotEmptyZero(high) ||
(NotEmptyZero(high) && iValue > high)) &&
IsValidSwing(
iValue,
iIDX,
barIndex,
iBar.symbol,
iBar.period,
X_SWING_HIGH //
);
if (has)
{
//
high = iValue;
highIDX = iIDX;
highAt = iBar.time;
}
}
//
iBar.Clean();
}
//
// Recent Low Swing ...
has =
IsXValid(lowAt) &&
NotEmptyZero(low) &&
IsValidIndex(lowIDX);
if (has)
{
//
has = iBar.Init(symbol, forPeriod, lowIDX);
has = has &&
swingLow.Init(
iBar.symbol,
iBar.period,
iBar.GetDown(),
low,
GetBarTime(iBar.symbol, iBar.period, lowIDX + swingsValidationLength - 1),
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_LOW),
lowAt //
);
if (has && forceRefineZones)
{
RefineZone(swingLow, 500, 5, X_PRICE_CLOSE);
}
}
//
// Recent High Swing ...
has =
IsXValid(highAt) &&
NotEmptyZero(high) &&
IsValidIndex(highIDX);
if (has)
{
//
has = iBar.Init(symbol, forPeriod, highIDX);
has = has &&
swingHigh.Init(
iBar.symbol,
iBar.period,
high,
iBar.GetUp(),
GetBarTime(iBar.symbol, iBar.period, lowIDX + swingsValidationLength - 1),
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_HIGH),
highAt //
);
if (has && forceRefineZones)
{
RefineZone(swingHigh, 500, 5, X_PRICE_CLOSE);
}
}
//
bool result = swingLow.IsValid() &&
swingHigh.IsValid();
//
return result;
}
bool HasOrderFlow(
XBoxZone &flow[],
int barIndex = 0,
int flowValidationLength = 5,
ENUM_X_DIRECTION flowDir = X_DIRECTION_NONE,
int loopback = 50,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
bool result = false;
//
XClean(flow);
//
// Validate ...
result =
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Normalizing Data ...
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
loopback = NormalizeInt(loopback, 5);
barIndex = kiParser.NormalizeBarIndex(barIndex);
flowValidationLength = NormalizeInt(flowValidationLength, 2);
//
// Handle Works ...
//
XOHCL iBar;
int iIndex = -1;
bool has = false;
XBoxZone tmpZone;
double iPrice = 0;
ENUM_X_PRICE iPriceType;
bool isBullish = !HasDirection(flowDir) || IsXBullish(flowDir);
bool isBearish = !HasDirection(flowDir) || IsXBearish(flowDir);
//
// Looping Reversal ...
int start = barIndex + loopback;
int end = barIndex;
for (int i = start; i > end; i--)
{
//
has = iBar.Init(forSymbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Check iBar is Low Swing ...
if (isBullish)
{
//
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
iPrice = iBar.GetPrice(iPriceType);
has = iPrice == iBar.FindLowest(iIndex, flowValidationLength, iPriceType);
has = has &&
IsValidSwing(
iPrice,
iBar.Index(),
barIndex,
iBar.symbol,
iBar.period,
X_SWING_LOW //
);
if (has)
{
//
// Flow Detected ...
tmpZone.Clean();
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_DOWN
: X_PRICE_UP;
has = tmpZone.Init(
iBar.symbol,
iBar.period,
iBar.GetPrice(iPriceType),
iPrice,
iBar.time,
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_LOW) //
);
if (has)
{
//
AddIfNotExists(
tmpZone,
flow //
);
//
tmpZone.Clean();
}
}
}
//
// Check iBar is High Swing ...
if (isBearish)
{
//
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
iPrice = iBar.GetPrice(iPriceType);
has = iPrice == iBar.FindHighest(iIndex, flowValidationLength, iPriceType);
has = has &&
IsValidSwing(
iPrice,
iBar.Index(),
barIndex,
iBar.symbol,
iBar.period,
X_SWING_HIGH //
);
if (has)
{
//
// Flow Detected ...
tmpZone.Clean();
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_UP
: X_PRICE_DOWN;
has = tmpZone.Init(
iBar.symbol,
iBar.period,
iPrice,
iBar.GetPrice(iPriceType),
iBar.time,
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_HIGH) //
);
if (has)
{
//
AddIfNotExists(
tmpZone,
flow //
);
//
tmpZone.Clean();
}
}
}
//
iBar.Clean();
tmpZone.Clean();
}
//
result = HasChild(flow);
//
return result;
}
bool IsValidSwing(
double price,
int swingIDX,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_SWING_TYPE swingType = X_SWING_NONE //
)
{
//
bool result = false;
//
result =
NotEmptyZero(price) &&
IsXValid(swingType) &&
IsValidIndex(swingIDX) &&
swingIDX >= barIndex;
if (!result)
{
return result;
}
//
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL iBar;
bool has = false;
for (int i = barIndex; i <= (swingIDX - barIndex); i++)
{
//
has = iBar.Init(forSymbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Check Price Break ...
has =
(swingType == X_SWING_LOW &&
iBar.low < price) ||
(swingType == X_SWING_HIGH &&
iBar.high > price);
if (has)
{
break;
}
//
iBar.Clean();
}
//
result = !has && !iBar.IsValid();
//
iBar.Clean();
//
return result;
}
// #endregion
// #region VolatilitySwitchedHigh ...
@@ -2196,12 +2675,29 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
// #endregion
// #region Bar Patterns ...
/*
* Check Recently Pattern Zone is Touched or not ...
*
* @param zone: XBoxZone, Touched Zone ...
* @param patterns: ENUM_X_BAR_PATTERN, Allowed to Check Patterns ...
* @param patternsDir: ENUM_X_DIRECTION, Allowed Directions ...
* @param price: double, a Price to Check Toch or Reject ...
* @param barIndex: int, Bar Index to Start Checking ...
* @param loopback: int, Loopback for Pattern Formations ...
* @param threshold: double, threshold for Pattern touch ...
* @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ...
* @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ...
*
* @return ( bool )
*/
bool HasRecentPatternTouched(
XBoxZone &zone,
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &patternsDir[],
double price,
int barIndex = 0,
int loopback = 5,
int threshold = 5,
double threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
@@ -2214,7 +2710,11 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
//
// Validate ...
result = NotEmptyZero(price);
result =
HasChild(patterns) &&
NotEmptyZero(price) &&
HasChild(patternsDir) &&
ArraySize(patterns) == ArraySize(patternsDir);
if (!result)
{
return result;
@@ -2244,7 +2744,21 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
//
// Preparing Pattern Analysis Config ...
iConfig.Default();
iConfig.FullPattern();
//
Copy(
patterns,
iConfig.allowedPatterns //
);
Copy(
patternsDir,
iConfig.allowedDirs //
);
//
// XAUUSD ...
iConfig.AddPattern(X_BAR_PATTERN_FVG);
iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// Looping Back ...