This commit is contained in:
2025-10-23 13:05:34 +03:30
parent 8b85de5de4
commit 2edb26cfc2
7 changed files with 1267 additions and 85 deletions
@@ -94,6 +94,7 @@ class XCBackTesterEA : public XCBase
//
XCAlert *eaAlert; // EA Scope Alert Handler ...
XCGuard *eaGuard; // EA Scope Guard Handler ...
XCTrade *eaTrader; // EA Scope Trade Handler ...
XCTarget *eaTarget; // EA Scope Target Manager ...
XCVolume *eaVolume; // EA Scope Volume Manager ...
@@ -310,6 +311,13 @@ class XCBackTesterEA : public XCBase
// Init Target Managers ...
eaTarget = new XCTarget(eaTrader, eaAlert);
//
// Initialize Guard Handler ...
eaGuard = new XCGuard(
eaAlert,
eaTrader //
);
//
eaVolume = new XCVolume();
result = eaVolume.Init(
@@ -369,6 +377,10 @@ class XCBackTesterEA : public XCBase
delete eaTrader;
ZeroMemory(eaTrader);
//
delete eaGuard;
ZeroMemory(eaGuard);
//
SpecifiedClean(mOnModifyEventHandlers);
SpecifiedClean(mStopLossEventHandlers);
@@ -406,7 +418,10 @@ class XCBackTesterEA : public XCBase
//
// Manage Positions Drawings ...
eaPositionDrawer.Update();
if (eaPositionDrawer != NULL)
{
eaPositionDrawer.Update();
}
}
/**
@@ -480,7 +495,10 @@ class XCBackTesterEA : public XCBase
eaTarget.HandleOnStopLossTriggered(deal);
//
eaPositionDrawer.HandleStopLossTriggered(deal);
if (eaPositionDrawer != NULL)
{
eaPositionDrawer.HandleStopLossTriggered(deal);
}
}
/**
@@ -498,7 +516,10 @@ class XCBackTesterEA : public XCBase
eaTarget.HandleOnTakeProfitTriggered(deal);
//
eaPositionDrawer.HandleOnTakeProfitTriggered(deal);
if (eaPositionDrawer != NULL)
{
eaPositionDrawer.HandleOnTakeProfitTriggered(deal);
}
}
/**
@@ -526,11 +547,15 @@ class XCBackTesterEA : public XCBase
);
//
eaPositionDrawer.HandleOnPositionForceClosed(
ticket,
position,
comment //
);
if (eaPositionDrawer != NULL)
{
//
eaPositionDrawer.HandleOnPositionForceClosed(
ticket,
position,
comment //
);
}
}
/**
@@ -598,11 +623,15 @@ class XCBackTesterEA : public XCBase
)
{
//
eaPositionDrawer.HandleOnPositionModified(
ticket,
profit,
comment //
);
if (eaPositionDrawer != NULL)
{
//
eaPositionDrawer.HandleOnPositionModified(
ticket,
profit,
comment //
);
}
}
/**
@@ -665,7 +694,10 @@ class XCBackTesterEA : public XCBase
eaTarget.AddExecutedSignal(signal);
//
eaPositionDrawer.AddExecutedSignal(signal);
if (eaPositionDrawer != NULL)
{
eaPositionDrawer.AddExecutedSignal(signal);
}
}
//
@@ -1650,6 +1650,254 @@ class XCMarketPatternDetector : public XCBase
return result;
}
bool IsConsolidationPattern(
XOHCL &bar,
XBoxZone &zone,
ENUM_X_DIRECTION &dir,
int validationLength = 5,
ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE,
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH,
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW //
)
{
//
// Descriptions:
// ===============
// Consolidation Zones Happens by Highest High and Lowest Low
// of Specified Range which Breakes From one Side ...
//
//
bool result = false;
//
// Prepare ...
zone.Clean();
CleanDirection(dir);
//
// Normalize ...
validationLength = NormalizeInt(validationLength, 3);
//
// Validate ...
result = bar.IsValid() &&
IsXValid(lowerPriceType) &&
IsXValid(upperPriceType) &&
IsXValid(breakPriceType);
if (!result)
{
return result;
}
//
// Define Requirements ...
XOHCL iBar;
bool has = false;
datetime to = NULL;
datetime from = NULL;
double iLow = EMPTY_VALUE;
bool hasLowShadow = false;
double lower = EMPTY_VALUE;
double upper = EMPTY_VALUE;
double iHigh = EMPTY_VALUE;
bool hasHighShadow = false;
double iPrice = EMPTY_VALUE;
bool isLowerBreaked = false;
bool isUpperBreaked = false;
//
// Loop Through Bars ...
int barIndex = bar.Index();
int idx = barIndex;
bool canLookup = IsValidIndex(idx);
while (canLookup)
{
//
// Initialize Indexed Bar ...
idx++;
iBar.Clean();
result = bar.BarAt(idx, iBar);
if (!result)
{
break;
}
//
// Update Time ...
if (idx == barIndex + 1)
{
to = iBar.time;
}
//
// Extract Low and High Price ...
iLow = iBar.GetPrice(lowerPriceType);
iHigh = iBar.GetPrice(upperPriceType);
result = NotEmptyZero(iLow) &&
NotEmptyZero(iHigh);
if (!result)
{
break;
}
//
// Check Bar Has Low/High Shadow ...
hasLowShadow = iBar.GetLowShadow() > iBar.GetHighShadow();
hasHighShadow = iBar.GetHighShadow() > iBar.GetLowShadow();
//
// Update Range Lower and Upper based on Shadows ...
//
// Lower ...
if (hasLowShadow)
{
//
// Check Can Update ...
has =
!NotEmptyZero(lower)
? true
: iLow < lower;
if (has)
{
lower = iLow;
}
}
//
// Upper ...
if (hasHighShadow)
{
//
// Check Can Update ...
has =
!NotEmptyZero(upper)
? true
: iHigh > upper;
if (has)
{
upper = iHigh;
}
}
//
// Check Price Breakes ...
iPrice = iBar.GetPrice(breakPriceType);
result = NotEmptyZero(iPrice);
if (!result)
{
break;
}
//
// Check Upper/Lower breakes ...
isLowerBreaked = iPrice < lower;
isUpperBreaked = iPrice > upper;
//
canLookup = (!isLowerBreaked && !isUpperBreaked);
if (!canLookup)
{
break;
}
//
from = iBar.time;
}
//
// Validate Calculations ...
result =
//
IsXValid(to) &&
IsXValid(from) &&
from < to &&
//
NotEmptyZero(lower) &&
NotEmptyZero(upper) &&
upper > lower
//
;
//
// Validate To Edge Breakes ...
if (result)
{
//
iPrice = bar.GetPrice(breakPriceType);
result = NotEmptyZero(iPrice);
//
// Validate To Edge Breakes ...
if (result)
{
//
isUpperBreaked = iPrice > upper;
isLowerBreaked = iPrice < lower;
//
// Validate To Break ...
result = isUpperBreaked || isLowerBreaked;
}
//
// Prepare Direction ...
if (result)
{
//
dir =
isUpperBreaked
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Validate Direction ...
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.to = to;
zone.dir = dir;
zone.from = from;
zone.at = bar.time;
zone.upper = upper;
zone.lower = lower;
zone.symbol = bar.symbol;
zone.period = bar.period;
zone.type = ToXString(X_BAR_PATTERN_CONSOLIDATION);
//
// Validate Zone ...
result = zone.IsValid();
//
// Validate Zone Length ...
if (result)
{
result = zone.FromIndex() - zone.ToIndex() >= validationLength;
}
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
CleanDirection(dir);
}
iBar.Clean();
//
return result;
}
//
// FVG ...
+272
View File
@@ -790,3 +790,275 @@ bool Strategy2HasSignal(
//
return result;
}
// =======================================
// Signaller 4:
// CONSOLIDATION Zones ...
// =======================================
/**
* 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;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Do ...
//
bool isConsolidation = poiDetector.IsConsolidationPattern(
pBar,
zone,
dir //
);
//
// Validating Consolidation Zone ...
int lastPeakOverLast = -1;
int lastValeUnderLast = -1;
//
// Bullish Consolidation ...
bool isConsolidationBullish =
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());
//
// 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)
{
//
zone.to = bar.time;
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.zonesWidth = 3;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrDarkOrange;
poiDrawer.DrawZone(zone, iConfig);
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 //
);
//
// 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;
}
@@ -452,6 +452,12 @@ int OnInit()
// detectorConfig.FullDetect();
// marketStructureDrawerConfig.FullDraw();
//
// Ignoring Position Drawer ...
delete eaExpert.eaPositionDrawer;
ZeroMemory(eaExpert.eaPositionDrawer);
eaExpert.eaPositionDrawer = NULL;
//
Print(ShortName, ": Initialized Successfully ...");
return INIT_SUCCEEDED;
@@ -518,6 +524,35 @@ void OnTick()
//
// Signallers Calling OnTick ...
fima1Signaller.OnTick(barIndex);
//
// Checking For Guard only When has Position ...
XPosition positions[];
int positionsCount = eaExpert.eaTrader.GetPositions(
positions,
fima1Signaller.symbol,
fima1Signaller.name,
fima1Signaller.period,
NULL, // All Types ...
true, // Filter By Magic ...
true // Force Clean ...
);
if (IsValidSize(positionsCount))
{
//
XGuard guards[];
int guardsCount = fima1Signaller.CheckForGuard(
guards,
positions,
barIndex //
);
if (IsValidSize(guardsCount))
{
//
// Handling Guards ...
eaExpert.eaGuard.DoGuards(guards);
}
}
}
//
+370
View File
@@ -2656,9 +2656,115 @@ class XCXFIMAHelper : public XCBaseHelper
return result;
}
bool IsSarSwitchedToBullish(int barIndex = 0)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
int pBarIndex = barIndex + 1;
//
bool isBullish = IsSarBullish(barIndex);
bool isPBullish = IsSarBullish(pBarIndex);
//
result = isBullish &&
!isPBullish;
//
return result;
}
bool IsSarSwitchedToBearish(int barIndex = 0)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
int pBarIndex = barIndex + 1;
//
bool isBearish = IsSarBearish(barIndex);
bool isPBearish = IsSarBearish(pBarIndex);
//
result = isBearish &&
!isPBearish;
//
return result;
}
//
// PV ...
bool IsPeakSame(int barIndex = 0)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double iC = GetPeak(barIndex);
double iP = GetPeak(barIndex + 1);
//
result = iC == iP &&
NotEmptyZero(iC);
//
return result;
}
bool IsValeSame(int barIndex = 0)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double iC = GetVale(barIndex);
double iP = GetVale(barIndex + 1);
//
result = iC == iP &&
NotEmptyZero(iC);
//
return result;
}
/**
* Check Peak Happens over Last ...
*
@@ -3153,6 +3259,270 @@ class XCXFIMAHelper : public XCBaseHelper
return result;
}
bool HasPVConsolidationZone(
XBoxZone &zone,
int barIndex = 0,
bool forcePVBreak = false,
bool forceHasSarSwitch = false //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Do ...
//
bool isPeakSame = IsPeakSame(barIndex);
bool isValeSame = IsValeSame(barIndex);
result = !(isPeakSame &&
isValeSame);
if (!result)
{
return result;
}
//
double iPeak = EMPTY_VALUE;
double iVale = EMPTY_VALUE;
//
int idx = barIndex;
bool canLookup = true;
while (canLookup)
{
//
idx++;
isPeakSame = IsPeakSame(idx);
isValeSame = IsValeSame(idx);
result = isPeakSame &&
isValeSame;
if (!result)
{
//
zone.from = GetBarTime(mSymbol, mPeriod, idx);
break;
}
//
if (idx == barIndex + 1)
{
//
zone.to = GetBarTime(
mSymbol,
mPeriod,
idx //
);
}
//
zone.from = GetBarTime(
mSymbol,
mPeriod,
idx //
);
//
iPeak = GetPeak(idx);
iVale = GetVale(idx);
//
zone.lower =
!NotEmptyZero(zone.lower)
? iVale
: MathMin(zone.lower, iVale);
//
zone.upper =
!NotEmptyZero(zone.upper)
? iPeak
: MathMax(zone.upper, iPeak);
}
//
// Validating Zone Params ...
result =
//
IsXValid(zone.to) &&
IsXValid(zone.from) &&
zone.from < zone.to &&
//
NotEmptyZero(zone.lower) &&
NotEmptyZero(zone.upper) &&
zone.upper > zone.lower
//
;
//
// Prepare Zone ...
if (result)
{
//
iPeak = GetPeak(barIndex);
iVale = GetVale(barIndex);
bool isPeakOverLast = IsPeakOverLast(barIndex);
bool isValeUnderLast = IsValeUnderLast(barIndex);
bool isValeBreak = iVale < zone.lower;
bool isPeakBreak = iPeak > zone.upper;
bool isPVBreak = isPeakBreak ||
isValeBreak;
//
zone.at = GetBarTime(mSymbol, mPeriod, barIndex);
zone.symbol = mSymbol;
zone.period = mPeriod;
zone.dir = (isPeakOverLast && !isValeUnderLast && isPVBreak)
? X_DIRECTION_BULLISH
: (isValeUnderLast && !isPeakOverLast && isPVBreak)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
zone.type = ToXString(X_BAR_PATTERN_CONSOLIDATION);
//
// Refine Zone Upper and Lower ...
if (zone.IsValid())
{
//
XOHCL iBar;
int zoneLoopback = zone.FromIndex() - zone.ToIndex();
result = zone.ToBar(iBar) &&
IsValidSize(zoneLoopback);
if (result)
{
//
double zoneLL = iBar.FindLowest(zoneLoopback, MODE_LOW);
double zoneHH = iBar.FindHighest(zoneLoopback, MODE_HIGH);
result = NotEmptyZero(zoneLL) &&
NotEmptyZero(zoneHH);
if (result)
{
//
zone.lower = zone.lower == zoneLL
? zone.lower
: MathMax(zone.lower, zoneLL);
//
zone.upper = zone.upper == zoneHH
? zone.upper
: MathMin(zone.upper, zoneHH);
}
}
//
iBar.Clean();
}
//
// Validate ...
result = zone.IsValid();
}
//
// Validate Zones From ...
if (result)
{
//
int idx = zone.FromIndex();
//
iPeak = GetPeak(idx);
iVale = GetVale(idx);
//
bool isValeOverLast = IsValeOverLast(idx);
bool isPeakUnderLast = IsPeakUnderLast(idx);
//
result =
result &&
(zone.IsBullish()
? !isPeakUnderLast
: zone.IsBearish()
? !isValeOverLast
: false);
}
//
// Apply Forces ...
//
// PV Break ...
// Peak or Vale must Breaked at Bar ...
if (result && forcePVBreak)
{
//
bool isPVBreaked =
(zone.IsBullish() && IsPeakOverLast(barIndex)) ||
(zone.IsBearish() && IsValeUnderLast(barIndex));
//
result = result &&
isPVBreaked;
}
//
// Other Loop based Forces ...
if (result && (forceHasSarSwitch))
{
//
bool hasSarSwitch = false;
//
int start = zone.ToIndex();
int end = zone.FromIndex();
for (int i = start; i <= end; i++)
{
//
// Check Sar Switches ...
if (forceHasSarSwitch && !hasSarSwitch)
{
//
hasSarSwitch =
zone.IsBullish()
? IsSarSwitchedToBullish(i)
: IsSarSwitchedToBearish(i);
}
}
//
// Validate Forces ...
if (forceHasSarSwitch)
{
//
result =
result &&
hasSarSwitch;
}
}
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
//
return result;
}
//
// HK ...
+12
View File
@@ -50,6 +50,7 @@ enum ENUM_X_BAR_PATTERN
X_BAR_PATTERN_SUPPORT = 14,
X_BAR_PATTERN_RESISTANCE = 15,
X_BAR_PATTERN_PULLBACK = 16,
X_BAR_PATTERN_CONSOLIDATION = 17,
};
/**
@@ -163,6 +164,11 @@ string ToXString(ENUM_X_BAR_PATTERN value)
case X_BAR_PATTERN_PULLBACK:
result = "XPULLBACK";
break;
//
case X_BAR_PATTERN_CONSOLIDATION:
result = "XCONSOLIDATION";
break;
}
//
@@ -257,6 +263,10 @@ ENUM_X_BAR_PATTERN ToBarPattern(string value)
{
result = X_BAR_PATTERN_PULLBACK;
}
else if (value == ToXString(X_BAR_PATTERN_CONSOLIDATION))
{
result = X_BAR_PATTERN_CONSOLIDATION;
}
//
return result;
@@ -290,6 +300,8 @@ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[])
Add(X_BAR_PATTERN_FVG, dest);
Add(X_BAR_PATTERN_SUPPORT, dest);
Add(X_BAR_PATTERN_RESISTANCE, dest);
Add(X_BAR_PATTERN_PULLBACK, dest);
Add(X_BAR_PATTERN_CONSOLIDATION, dest);
//
return ArraySize(dest);
@@ -402,20 +402,12 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Handle Partial Close Position if Reached TP 1.5 ...
// iTarget.Clean();
// iTarget.doRF = true;
// iTarget.actingDistance = 10;
// iTarget.volumeMultiplier = 0.5;
// iTarget.target = isBullish ? entry + (1.8 * risk) : entry - (1.8 * risk);
// // iTarget.tpValue = isBullish ? entry + (2.5 * risk) : entry - (2.5 * risk);
// AddRef(iTarget, iTargets);
//
// Reward 3 Target ...
iTarget.Clean();
iTarget.doRF = true;
iTarget.actingDistance = 0;
iTarget.target = isBullish ? entry + (3 * risk) : entry - (3 * risk);
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);
//
@@ -432,58 +424,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Here we Can Do Target Preparing if Signaller Restricted and
// then ignore restrictions if required ...
// //
// // Risk Free On Entry:
// iTarget.Clean();
// iTarget.doRF = true;
// iTarget.actingDistance = 10 * _point; // (5 * spread) / _point;
// iTarget.target = isBullish ? entry + risk : entry - risk; // isBullish ? entry + (2 * spread) : entry - (2 * spread);
// AddRef(iTarget, iTargets);
// //
// // Partial Close Position Half on TP 1 ...
// // Increase Rewards to TP 3 ...
// iTarget.Clean();
// iTarget.actingDistance = 1;
// iTarget.volumeMultiplier = 0.5;
// iTarget.target = isBullish ? entry + risk : entry - risk;
// iTarget.tpValue = isBullish ? entry + (2.5 * risk) : entry - (2.5 * risk);
// AddRef(iTarget, iTargets);
// //
// // Reset Restrictions ...
// if (loosingTrades == 1)
// {
// ResetRestrictions();
// }
//
if (loosingTrades > 2)
{
//
if (IsXValid(restUntil) && iBar.time > restUntil)
{
//
WinTrade();
restUntil = NULL;
}
else
{
//
XOHCL rBar;
bool has = rBar.Init(iZone.symbol, PERIOD_W1, 0);
if (has)
{
//
restUntil = rBar.NextAt(); // + PeriodSeconds(PERIOD_D1);
Print("Rest Until: ", restUntil);
}
//
rBar.Clean();
}
}
ResetRestrictions();
}
//
@@ -537,9 +478,73 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
SpecifiedClean(guards);
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
// Requirements ...
XGuard iGuard;
bool has = false;
//
// Force Hedging ...
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;
}
//
// 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);
//
// Cleanup ...
iGuard.Clean();
//
return result;
}
@@ -581,11 +586,23 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// dir //
// );
//
// if (!result)
// {
// //
// result = Strategy3HasSignal(
// bar,
// zone,
// targets,
// dir //
// );
// }
//
if (!result)
{
//
result = Strategy3HasSignal(
result = Strategy4HasSignal(
bar,
zone,
targets,
@@ -593,11 +610,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
);
}
//
if (result)
{
// Print("Salam");
}
// //
// if (result)
// {
// Print("Salam");
// }
//
return result;
@@ -1211,6 +1228,202 @@ 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 ...
// XFIMA Consolidation ...
//
bool isConsolidation = fimaHelper.HasPVConsolidationZone(
zone,
pBar.Index(),
true, // Force PV Break ...
true // Force Has Sar Switch ...
);
//
isBullish =
isConsolidation &&
zone.IsBullish();
//
isBearish =
isConsolidation &&
zone.IsBearish();
//
// 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)
//
);
//
// 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;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir = zone.dir;
zone.to = bar.time;
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.zonesWidth = 3;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrDarkOrange;
poiDrawer.DrawZone(zone, iConfig);
Print("Consolidation");
}
//
// 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;
}
//
};