last works ...

This commit is contained in:
2025-10-23 16:32:30 +03:30
parent 2edb26cfc2
commit 97bb7b4509
6 changed files with 1237 additions and 583 deletions
@@ -365,9 +365,13 @@ class XCBackTesterEA : public XCBase
ZeroMemory(eaTarget);
//
eaPositionDrawer.Destroy();
delete eaPositionDrawer;
ZeroMemory(eaPositionDrawer);
if (eaPositionDrawer != NULL)
{
//
eaPositionDrawer.Destroy();
delete eaPositionDrawer;
ZeroMemory(eaPositionDrawer);
}
//
delete eaVolume;
@@ -1898,6 +1898,334 @@ class XCMarketPatternDetector : public XCBase
return result;
}
bool HasOrderFlow(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
XBoxZone &orderFlow[],
int orderFlowValidation = 2,
bool containsOBs = false,
bool containsFVGs = true,
bool containsSupportResistances = false,
int zonesLoopback = 5,
int zonesValidationLength = 21,
int maxRequiredZone = 0,
int loopback = 100 //
)
{
//
bool result = false;
//
// Prepare ...
XClean(orderFlow);
CleanDirection(dir);
//
// Normalize ...
loopback = NormalizeInt(loopback, 10);
zonesLoopback = NormalizeInt(zonesLoopback, 3);
maxRequiredZone = NormalizeInt(maxRequiredZone, 0);
orderFlowValidation = NormalizeInt(orderFlowValidation, 1);
zonesValidationLength = NormalizeInt(zonesValidationLength, 3);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Do ...
//
// Collectiong Zones ...
XBoxZone tmp;
XBoxZone tmps[];
XBoxZone _zones[];
XBoxZone bullishZones[];
XBoxZone bearishZones[];
int bullishZonesCount = 0;
int bearishZonesCount = 0;
//
// Order Blocks ...
if (containsOBs)
{
//
XClean(tmps);
CollectOBs(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
FillNotExists(_zones, tmps);
}
//
// Fair Value Gaps ...
if (containsFVGs)
{
//
XClean(tmps);
CollectFVGs(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
FillNotExists(_zones, tmps);
}
//
// Support and Resistances ...
if (containsSupportResistances)
{
//
XClean(tmps);
CollectZones(bar, tmps, zonesLoopback, maxRequiredZone, loopback);
FillNotExists(_zones, tmps);
}
//
// Validate Zones ...
result = HasChild(_zones);
//
// Extract Only Validated Zones ...
if (result)
{
//
ValidateBoxes(
_zones,
bar.Index() //
);
//
result = HasChild(_zones);
}
//
// Separate Zones Direction ...
if (result)
{
//
bullishZonesCount = ExtractByDirection(bullishZones, _zones, X_DIRECTION_BULLISH);
bearishZonesCount = ExtractByDirection(bearishZones, _zones, X_DIRECTION_BEARISH);
//
result = IsValidSize(bullishZonesCount) ||
IsValidSize(bearishZonesCount);
}
//
// Looking for Sequences of Zones ...
if (result)
{
//
int idx = -1;
bool has = false;
XBoxZone bullOrderFlow[];
XBoxZone bearOrderFlow[];
//
// Bullish OrderFlow ...
//
// Sorting ...
Copy(bullishZones, bullOrderFlow);
Sort(
bullOrderFlow,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH,
orderFlowValidation + 1 //
);
bool hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation;
if (hasBullishOrderFlow)
{
//
// Validate Order Flow ...
Copy(bullOrderFlow, tmps);
XClean(bullOrderFlow);
while (HasChild(tmps))
{
//
tmp.Clean();
tmp = tmps[0];
ArrayRemove(tmps, 0, 1);
//
idx = GetHighest(tmps);
has = !IsValidIndex(idx)
? true
: tmps[idx].lower < tmp.lower;
if (has)
{
AddIfNotExists(tmp, bullOrderFlow);
}
}
//
hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation;
}
//
// Bearish OrderFlow ...
//
// Sorting ...
Copy(bearishZones, bearOrderFlow);
Sort(
bearOrderFlow,
X_SORT_BY_DATE,
X_DIRECTION_BULLISH,
orderFlowValidation + 1 //
);
bool hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation;
if (hasBearishOrderFlow)
{
//
// Validate Order Flow ...
Copy(bearOrderFlow, tmps);
XClean(bearOrderFlow);
while (HasChild(tmps))
{
//
tmp.Clean();
tmp = tmps[0];
ArrayRemove(tmps, 0, 1);
//
idx = GetLowest(tmps);
has = !IsValidIndex(idx)
? true
: tmps[idx].upper > tmp.upper;
if (has)
{
AddIfNotExists(tmp, bearOrderFlow);
}
}
//
hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation;
}
//
result = hasBullishOrderFlow ||
hasBearishOrderFlow;
//
// Validate Order Flows ...
if (result)
{
//
has = (hasBullishOrderFlow && !hasBearishOrderFlow) ||
(hasBearishOrderFlow && !hasBullishOrderFlow);
//
// When only Have One Direction ...
if (has)
{
//
if (hasBullishOrderFlow)
{
//
dir = X_DIRECTION_BULLISH;
Copy(bullOrderFlow, orderFlow);
}
else if (hasBearishOrderFlow)
{
//
dir = X_DIRECTION_BEARISH;
Copy(bearOrderFlow, orderFlow);
}
}
//
// When Two Direction Exists ...
else
{
//
// Retrieve Oldest Of Bullish / Bearish ...
int oldestBullIDX = GetOldest(bullOrderFlow);
int oldestBearIDX = GetOldest(bearOrderFlow);
result = IsValidIndex(oldestBullIDX) &&
IsValidIndex(oldestBearIDX);
if (result)
{
//
dir =
bullOrderFlow[oldestBullIDX].from > bearOrderFlow[oldestBearIDX].from
? X_DIRECTION_BULLISH
: bearOrderFlow[oldestBearIDX].from > bullOrderFlow[oldestBullIDX].from
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
//
result = HasDirection(dir);
if (result)
{
//
if (IsXBullish(dir))
{
Copy(bullOrderFlow, orderFlow);
}
else if (IsXBearish(dir))
{
Copy(bearOrderFlow, orderFlow);
}
}
}
}
//
XClean(bullOrderFlow);
XClean(bearOrderFlow);
//
result = HasChild(orderFlow) &&
HasDirection(dir);
}
//
// Validate Price ...
if (result)
{
//
int idx = -1;
if (IsXBullish(dir))
{
//
idx = GetHighest(orderFlow);
result = IsValidIndex(idx) &&
bar.low > orderFlow[idx].upper;
}
else
{
//
idx = GetLowest(orderFlow);
result = IsValidIndex(idx) &&
bar.high < orderFlow[idx].lower;
}
}
//
// Update To Time of Order Flow ...
if (result)
{
UpdateToTime(orderFlow, bar.time);
}
//
// Cleanup ...
if (!result)
{
//
XClean(orderFlow);
CleanDirection(dir);
}
tmp.Clean();
XClean(tmps);
XClean(_zones);
XClean(bullishZones);
XClean(bearishZones);
//
return result;
}
//
// FVG ...
+415 -450
View File
@@ -176,11 +176,11 @@ bool StrategyXHasSignal(
}
// =======================================
// Signaller 1:
// Signallers:
// =======================================
/**
* Check Bar Has Signal Based on Strategy 1 ...
* Check Bar Has Signal Based on Strategy 3 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
@@ -216,6 +216,298 @@ bool Strategy1HasSignal(
//
// Define Requirements ...
//
XOHCL pBar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
if (!result)
{
//
pBar.Clean();
return result;
}
//
// Reading Conditions ...
int pullBackStartBar = -1;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
zone,
dir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(dir);
bool isPullbackBearish = isPullBack &&
IsXBearish(dir);
if (isPullBack)
{
pullBackStartBar = zone.FromIndex();
}
//
// Reading HK Bond ...
//
double pHKBondUpper = fimaHelper.GetHKBondUpper(pBar.Index());
double pHKBondLower = fimaHelper.GetHKBondLower(pBar.Index());
int overHKBondUpperCount = fimaHelper.CountOverHKBondUpper(pullBackStartBar, X_PRICE_LOW);
int underHKBondLowerCount = fimaHelper.CountUnderHKBondLower(pullBackStartBar, X_PRICE_HIGH);
//
// Reading PV Requirements ...
//
int lastPeakOverLastIDX = -1;
int lastValeUnderLastIDX = -1;
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
int samePeaks = fimaHelper.CountSamePeaks(pBar.Index());
int sameVales = fimaHelper.CountSameVales(pBar.Index());
fimaHelper.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index());
fimaHelper.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index());
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Bar Patterns ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
//
// Try To Find Affected Zone ...
//
// Collecting Zones ...
XBoxZone zones[];
XBoxZone affectedZones[];
XBoxZone affectedZonesBullish[];
XBoxZone affectedZonesBearish[];
int zonesCount = poiDetector.CollectZones(
pBar,
zones, //
5, // Zones Loopback ...
3 // Zones Validation Length ...
// Required Zones ...
// Loopback ...
);
int affectedZonesCount = ExtractAffectedZones(
pBar,
zones,
affectedZones //
);
int affectedZonesBullishCount = ExtractByDirection(
affectedZonesBullish,
affectedZones,
X_DIRECTION_BULLISH //
);
int affectedZonesBearishCount = ExtractByDirection(
affectedZonesBearish,
affectedZones,
X_DIRECTION_BEARISH //
);
//
int insideBullishIDX = -1;
int insideBearishIDX = -1;
bool hasBullishInside =
pBar.IsBullish() &&
HasInside(
insideBullishIDX,
pBar,
affectedZonesBullish //
);
bool hasBearishInside =
pBar.IsBearish() &&
HasInside(
insideBearishIDX,
pBar,
affectedZonesBearish //
);
//
// Do ...
//
isBullish =
//
hasBullishInside &&
isPullbackBullish &&
isPBarHasBullishPatterns &&
fimaHelper.IsSarBullish(pBar.Index()) &&
(pVale >= affectedZonesBullish[insideBullishIDX].lower &&
pVale <= affectedZonesBullish[insideBullishIDX].upper)
//
;
//
isBearish =
//
hasBearishInside &&
isPullbackBearish &&
isPBarHasBearishPatterns &&
fimaHelper.IsSarBearish(pBar.Index()) &&
(pPeak >= affectedZonesBearish[insideBearishIDX].lower &&
pPeak <= affectedZonesBearish[insideBearishIDX].upper)
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
if (isBullish)
{
//
poiDrawer.DrawZone(
affectedZonesBullish[insideBullishIDX],
structureDrawConfig.drawConfig //
);
}
else
{
//
poiDrawer.DrawZone(
affectedZonesBearish[insideBearishIDX],
structureDrawConfig.drawConfig //
);
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
if (isBullish)
{
zone = affectedZonesBullish[insideBullishIDX];
}
else
{
zone = affectedZonesBearish[insideBearishIDX];
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
XClean(zones);
pBarAnalysis.Clean();
XClean(affectedZones);
XClean(affectedZonesBullish);
XClean(affectedZonesBearish);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @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();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
@@ -495,307 +787,6 @@ bool Strategy1HasSignal(
return result;
}
// =======================================
// Signaller 2:
// =======================================
/**
* Check Bar Has Signal Based on Strategy 1 ...
*
* @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();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
if (!result)
{
//
pBar.Clean();
return result;
}
//
// Reading Conditions ...
int pullBackStartBar = -1;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
zone,
dir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(dir);
bool isPullbackBearish = isPullBack &&
IsXBearish(dir);
if (isPullBack)
{
pullBackStartBar = zone.FromIndex();
}
//
// Reading HK Bond ...
//
double pHKBondUpper = fimaHelper.GetHKBondUpper(pBar.Index());
double pHKBondLower = fimaHelper.GetHKBondLower(pBar.Index());
int overHKBondUpperCount = fimaHelper.CountOverHKBondUpper(pullBackStartBar, X_PRICE_LOW);
int underHKBondLowerCount = fimaHelper.CountUnderHKBondLower(pullBackStartBar, X_PRICE_HIGH);
//
// Reading PV Requirements ...
//
int lastPeakOverLastIDX = -1;
int lastValeUnderLastIDX = -1;
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
int samePeaks = fimaHelper.CountSamePeaks(pBar.Index());
int sameVales = fimaHelper.CountSameVales(pBar.Index());
fimaHelper.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index());
fimaHelper.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index());
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Bar Patterns ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
//
// Try To Find Affected Zone ...
//
// Collecting Zones ...
XBoxZone zones[];
XBoxZone affectedZones[];
XBoxZone affectedZonesBullish[];
XBoxZone affectedZonesBearish[];
int zonesCount = poiDetector.CollectZones(
pBar,
zones, //
5, // Zones Loopback ...
3 // Zones Validation Length ...
// Required Zones ...
// Loopback ...
);
int affectedZonesCount = ExtractAffectedZones(
pBar,
zones,
affectedZones //
);
int affectedZonesBullishCount = ExtractByDirection(
affectedZonesBullish,
affectedZones,
X_DIRECTION_BULLISH //
);
int affectedZonesBearishCount = ExtractByDirection(
affectedZonesBearish,
affectedZones,
X_DIRECTION_BEARISH //
);
//
int insideBullishIDX = -1;
int insideBearishIDX = -1;
bool hasBullishInside =
pBar.IsBullish() &&
HasInside(
insideBullishIDX,
pBar,
affectedZonesBullish //
);
bool hasBearishInside =
pBar.IsBearish() &&
HasInside(
insideBearishIDX,
pBar,
affectedZonesBearish //
);
//
// Do ...
//
isBullish =
//
hasBullishInside &&
isPullbackBullish &&
isPBarHasBullishPatterns &&
fimaHelper.IsSarBullish(pBar.Index()) &&
(pVale >= affectedZonesBullish[insideBullishIDX].lower &&
pVale <= affectedZonesBullish[insideBullishIDX].upper)
//
;
//
isBearish =
//
hasBearishInside &&
isPullbackBearish &&
isPBarHasBearishPatterns &&
fimaHelper.IsSarBearish(pBar.Index()) &&
(pPeak >= affectedZonesBearish[insideBearishIDX].lower &&
pPeak <= affectedZonesBearish[insideBearishIDX].upper)
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
if (isBullish)
{
//
poiDrawer.DrawZone(
affectedZonesBullish[insideBullishIDX],
structureDrawConfig.drawConfig //
);
}
else
{
//
poiDrawer.DrawZone(
affectedZonesBearish[insideBearishIDX],
structureDrawConfig.drawConfig //
);
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
if (isBullish)
{
zone = affectedZonesBullish[insideBullishIDX];
}
else
{
zone = affectedZonesBearish[insideBearishIDX];
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
XClean(zones);
pBarAnalysis.Clean();
XClean(affectedZones);
XClean(affectedZonesBullish);
XClean(affectedZonesBearish);
//
return result;
}
// =======================================
// Signaller 4:
// CONSOLIDATION Zones ...
// =======================================
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
@@ -806,7 +797,7 @@ bool Strategy2HasSignal(
*
* @return ( bool )
*/
bool Strategy4HasSignal(
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
@@ -854,131 +845,135 @@ bool Strategy4HasSignal(
return result;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Do ...
// XFIMA Consolidation ...
//
bool isConsolidation = poiDetector.IsConsolidationPattern(
pBar,
bool isConsolidation = fimaHelper.HasPVConsolidationZone(
zone,
dir //
pBar.Index(),
true, // Force PV Break ...
true // Force Has Sar Switch ...
);
//
// Validating Consolidation Zone ...
int lastPeakOverLast = -1;
int lastValeUnderLast = -1;
isBullish =
isConsolidation &&
zone.IsBullish();
//
// Bullish Consolidation ...
bool isConsolidationBullish =
isBearish =
isConsolidation &&
IsXBullish(dir) &&
fimaHelper.FindLastPeakOverLast(
lastPeakOverLast,
zone.ToIndex(),
zone.FromIndex() - zone.ToIndex() //
) &&
fimaHelper.IsSarBullish(pBar.Index());
//
// Bearish Consolidation ...
bool isConsolidationBearish =
isConsolidation &&
IsXBearish(dir) &&
fimaHelper.FindLastValeUnderLast(
lastValeUnderLast,
zone.ToIndex(),
zone.FromIndex() - zone.ToIndex() //
) &&
fimaHelper.IsSarBearish(pBar.Index());
zone.IsBearish();
//
// Validate based on Bars Patterns ...
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isConsolidationBullish =
isConsolidationBullish &&
isPBarHasBullishPatterns;
//
isConsolidationBearish =
isConsolidationBearish &&
isPBarHasBearishPatterns;
//
// Validate Based on Same Peaks and Vales ...
//
int samePVValidationLength = 3;
int samePeaks = fimaHelper.CountSamePeaks(pBar.Index(), (zone.FromIndex() - zone.ToIndex()));
int sameVales = fimaHelper.CountSameVales(pBar.Index(), (zone.FromIndex() - zone.ToIndex()));
//
bool isPeakValid = samePeaks >= samePVValidationLength;
bool isValeValid = sameVales >= samePVValidationLength;
bool isPVValid = isPeakValid ||
isValeValid;
//
isConsolidationBullish =
isConsolidationBullish &&
isPVValid;
//
isConsolidationBearish =
isConsolidationBearish &&
isPVValid;
//
// Validation Consolidation ...
isConsolidation =
isConsolidationBullish ||
isConsolidationBearish;
//
if (isConsolidation)
bool validateByBarPatterns = true;
if (validateByBarPatterns)
{
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
// Checking PullBack ...
bool validateByPullback = false;
if (validateByPullback)
{
//
XBoxZone pullback;
ENUM_X_DIRECTION pullbackDir;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
pullback,
pullbackDir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(pullbackDir);
bool isPullbackBearish = isPullBack &&
IsXBearish(pullbackDir);
//
isBullish =
isBullish &&
isPullbackBullish;
//
isBearish =
isBearish &&
isPullbackBearish;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir = zone.dir;
zone.to = bar.time;
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.zonesWidth = 3;
@@ -988,48 +983,18 @@ bool Strategy4HasSignal(
Print("Consolidation");
}
//
isBullish =
//
false
//
;
//
isBearish =
//
false
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
// zone.Clean();
// result = ToBox(
// p2Bar,
// zone,
// dir,
// X_BAR_PATTERN_PINNED //
// );
//
// Manage Stops ...
+1 -1
View File
@@ -362,7 +362,7 @@ int OnInit()
eaSignallerRiskInPoint, // Default Risk In Points ...
eaSignallerVolume // Defaul Volume ...
);
fima1Signaller.slAdditionDistance = 15;
fima1Signaller.slAdditionDistance = 30;
fima1Signaller.AddOnSignalEventHandler(OnSignalTriggered);
//
+66 -3
View File
@@ -3268,6 +3268,70 @@ bool AddIfNotExists(
//
return result;
}
template <typename T>
int FillNotExists(
T &dest[],
T &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int maxAllowed = 0 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
maxAllowed = NormalizeInt(maxAllowed, 0);
//
// Validate ...
bool has = HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has =
source[i].IsValid() &&
(!HasDirection(forDir) || forDir == source[i].dir);
if (!has)
{
continue;
}
//
has = AddIfNotExists(source[i], dest);
if (has)
{
result++;
}
}
//
// Handle Cleanup Collection
// if Max Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
dest,
maxAllowed //
);
}
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
@@ -4774,9 +4838,9 @@ bool ToResistanceBox(
/**
* Remove Breaked Zones from a Collection ...
*
*
* @param source: XBoxZone, reference to Specified Collection ...
*
*
* @return ( int )
*/
int RemoveBreakedZones(XBoxZone &source[])
@@ -5465,7 +5529,6 @@ int ExtractBreakeds(
return result;
}
/**
* Collect all Bars which Breakes Specified Zone ...
*
@@ -396,19 +396,29 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Preparing Signal Targets ...
XTarget iTarget;
double spread = GetSpread(iZone.symbol);
double entry = GetEntry(iZone.symbol, iZone.dir);
double risk = MathAbs(entry - (isBullish ? iZone.lower : iZone.upper));
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, iZone.dir);
double risk = MathAbs(entry - slPrice);
//
// Ignore Signal if Risk is too Much ...
bool hasToomuchRisk = risk > (iZone.upper - iZone.lower) + slAddition + (100 * _point);
if (hasToomuchRisk)
{
//
iZone.Clean();
Print("Too Much Risk ...");
}
//
// Handle Partial Close Position if Reached TP 1.5 ...
iTarget.Clean();
iTarget.doRF = false;
iTarget.actingDistance = 5;
iTarget.doRFOnEntry = false;
iTarget.volumeMultiplier = 0.5;
iTarget.target = isBullish ? entry + (4 * risk) : entry - (4 * risk);
AddRef(iTarget, iTargets);
// iTarget.Clean();
// iTarget.doRF = false;
// iTarget.actingDistance = 5;
// iTarget.doRFOnEntry = false;
// iTarget.volumeMultiplier = 0.5;
// iTarget.target = isBullish ? entry + (4 * risk) : entry - (4 * risk);
// AddRef(iTarget, iTargets);
//
// Handle Ignore Signal Targets if Forced ...
@@ -429,14 +439,15 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Prepare Founded Signal ...
has = PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
has = iZone.IsValid() &&
PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
//
@@ -492,51 +503,57 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Force Hedging ...
bool forceHedging = (positionsCount >= 2);
if (forceHedging)
{
//
// Minimum Required Reward ...
double minRequiredReward = 1.5;
// bool forceHedging = (positionsCount >= 2);
// if (forceHedging)
// {
// //
// // Minimum Required Reward ...
// double minRequiredReward = 1.5;
//
// Summarizing Risk and Reward of Collections ...
double risk = 0;
double reward = 0;
for (int i = 0; i < positionsCount; i++)
{
//
risk += positions[i].GetRisk() + positions[i].commission + (-1 * positions[i].swap);
reward += positions[i].profit;
}
// //
// // Summarizing Risk and Reward of Collections ...
// // double risk = 0;
// // double volume = 0;
// // double reward = 0;
// // for (int i = 0; i < positionsCount; i++)
// // {
// // //
// // risk += positions[i].GetRisk() + positions[i].commission + (-1 * positions[i].swap);
// // reward += positions[i].profit;
// // volume += positions[i].volume;
// // }
//
// Calculating Can Hedge rops ...
has = reward >= (risk * minRequiredReward);
if (has)
{
//
iGuard.Clean();
iGuard.force = true;
iGuard.symbol = symbol;
iGuard.period = period;
iGuard.provider = name;
iGuard.time = TimeCurrent();
iGuard.action = X_GUARD_ACTION_HEDGE;
// // //
// // risk *= volume;
// // reward *= volume;
//
// Validate Guard ...
has = iGuard.IsValid();
if (has)
{
//
AddRef(
iGuard,
guards //
);
}
}
}
// // //
// // // Calculating Can Hedge rops ...
// // has = reward >= (risk * minRequiredReward);
// // if (has)
// // {
// // //
// // iGuard.Clean();
// // iGuard.force = true;
// // iGuard.symbol = symbol;
// // iGuard.period = period;
// // iGuard.provider = name;
// // iGuard.time = TimeCurrent();
// // iGuard.action = X_GUARD_ACTION_HEDGE;
// // //
// // // Validate Guard ...
// // has = iGuard.IsValid();
// // if (has)
// // {
// // //
// // AddRef(
// // iGuard,
// // guards //
// // );
// // }
// // }
// }
//
result = ArraySize(guards);
@@ -579,27 +596,58 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
bool result = false;
//
// result = Strategy2HasSignal(
// bar,
// zone,
// targets,
// dir //
// );
// Signaller Flags ...
bool useSignaller1 = true;
bool useSignaller2 = true;
bool useSignaller3 = true;
bool useSignaller4 = false;
//
// if (!result)
// {
// //
// result = Strategy3HasSignal(
// bar,
// zone,
// targets,
// dir //
// );
// }
// Validator Flags ...
bool validateByOrderFlow = true;
//
if (!result)
// Signaller 1 ...
if (!result && useSignaller1)
{
//
result = Strategy1HasSignal(
bar,
zone,
targets,
dir //
);
}
//
// Signaller 2 ...
if (!result && useSignaller2)
{
//
result = Strategy2HasSignal(
bar,
zone,
targets,
dir //
);
}
//
// Signaller 3 ...
if (!result && useSignaller3)
{
//
result = Strategy3HasSignal(
bar,
zone,
targets,
dir //
);
}
//
// Signaller 4 ...
if (!result && useSignaller4)
{
//
result = Strategy4HasSignal(
@@ -610,6 +658,40 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
);
}
//
// Validate Signals by Order Flow ...
if (validateByOrderFlow)
{
//
// Detecting OrderFlow ...
XBoxZone orderFlow[];
ENUM_X_DIRECTION orderFlowDir;
bool hasOrderFlow = poiDetector.HasOrderFlow(
bar,
orderFlowDir,
orderFlow,
2,
false, // Contains OB ...
true, // Contains FVG ...
false // Contains Support and Resistances ...
);
//
bool isBullish = hasOrderFlow &&
IsXBullish(dir) &&
IsXBullish(orderFlowDir);
//
bool isBearish = hasOrderFlow &&
IsXBearish(dir) &&
IsXBearish(orderFlowDir);
//
// Summarizing result ...
result = isBullish ||
isBearish;
}
// //
// if (result)
// {
@@ -630,7 +712,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
*
* @return ( bool )
*/
bool Strategy2HasSignal(
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
@@ -922,7 +1004,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
*
* @return ( bool )
*/
bool Strategy3HasSignal(
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
@@ -1238,7 +1320,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
*
* @return ( bool )
*/
bool Strategy4HasSignal(
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
@@ -1310,57 +1392,102 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Validate based on Bars Patterns ...
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
bool validateByBarPatterns = true;
if (validateByBarPatterns)
{
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
// Checking PullBack ...
bool validateByPullback = false;
if (validateByPullback)
{
//
XBoxZone pullback;
ENUM_X_DIRECTION pullbackDir;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
pullback,
pullbackDir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(pullbackDir);
bool isPullbackBearish = isPullBack &&
IsXBearish(pullbackDir);
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
isBullish =
isBullish &&
isPullbackBullish;
//
isBearish =
isBearish &&
isPullbackBearish;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
// Validate ...
@@ -1424,6 +1551,173 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
return result;
}
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @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 Strategy4HasSignal(
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();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Do ...
//
// Detecting OrderFlow ...
XBoxZone orderFlow[];
bool hasOrderFlow = poiDetector.HasOrderFlow(
pBar,
dir,
orderFlow,
2,
false, // Contains OB ...
true, // Contains FVG ...
false // Contains Support and Resistances ...
);
//
isBullish = hasOrderFlow &&
IsXBullish(dir);
//
isBearish = hasOrderFlow &&
IsXBearish(dir);
//
result = isBullish ||
isBearish;
if (result)
{
//
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
Print("OrderFlow Detected ...");
}
//
isBullish =
//
false
//
;
//
isBearish =
//
false
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
//
// Manage Stops ...
if (result)
{
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
};