Files
MQL5Data/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5
T
2025-03-23 03:46:13 +03:30

1816 lines
45 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121 SMC Signal Class
// -------------------------------------------------
// Name: XWZ
// Description: provide all Signalling functions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
#include "../Libraries/x-121.smc.guard.lib.mq5"
#include "../Libraries/x-121.smc.lib.mq5"
#include "./x-121.smc.xwz.signal.lib.mq5"
//
// Definition ...
class XCX121SMCXWZSignalDetector : public XCBase
{
//
public:
//
// Props ...
bool useGuards;
double rfRewar;
bool useQuarterTargets;
X121SMCStrategyXWZWorkingZone workingZone;
X121SMCStrategyXWZSignalConditions mConditions;
X121SMCStrategyXWZSignalConditions mConditionsCollection[];
//
// Constructor(s) ...
XCX121SMCXWZSignalDetector(
string _symbol,
ENUM_TIMEFRAMES _period //
)
{
//
symbol = _symbol;
period = _period;
Init();
}
//
// Deconstructor ...
~XCX121SMCXWZSignalDetector()
{
DeInit();
}
//
//
//
//
// Detect Setup Conditions ...
bool DetectSignalSetup(
//
X121SMCStrategySignalProviderData &provider,
//
double maxAllowedSLDistanceInPoint = 300
//
)
{
//
bool result = false;
//
// Validate Cycle Helpers ...
result = provider.IsValid();
if (!result)
{
//
mConditions.Clean();
//
return result;
}
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
mConditions.symbol = symbol;
mConditions.period = period;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
// Cycles Conditions ...
result = provider.Prepare(
zIndex,
loopback,
false, // Trigger ...
true, // Decision ...
true, // Analyse ...
true, // Verification ...
true, // Consolidation ...
true // Vision ...
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// Select Drawer Class ...
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
//
XOHCL consolidationZBar;
result = provider.consolidationCycleHelper.GetBar(
consolidationZBar,
zIndex //
);
if (!result)
{
//
consolidationZBar.Clean();
return result;
}
//
bool drawBar = false;
if (drawBar)
{
//
DrawBar(
consolidationZBar,
drawer //
);
}
//
//
//
//
// Setup Conditions ...
double sls[];
double sl = 0;
double pivot = 0;
double point = 0;
double targets[];
double reward = 0;
XSignalBox signalBox;
bool hasTrend = false;
bool hasPriority = false;
double amountPercent = -1;
bool hasSignalBox = false;
bool hasWaitingBoxes = false;
bool hasRewardAmount = false;
ENUM_X_DIRECTION trend = X_DIRECTION_NONE;
ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE;
ENUM_X121SMC_XWZ_PRIORITY priority = X121SMC_XWZ_PRIORITY_NONE;
ENUM_X121SMC_XWZ_PROVIDERS signalProvider = X121SMC_XWZ_PROVIDER_NONE;
//
//
//
//
// First We Have to Has Working Zone ...
bool hasWorkingZone = workingZone.IsValid();
if (!hasWorkingZone)
{
//
hasWorkingZone = workingZone.Init(
symbol,
period,
zIndex,
provider //
);
}
//
// Update Working Zone ...
if (hasWorkingZone)
{
//
// Reset POI Detector Required POI(s) ...
provider.MaxRequiredPOIs(50);
//
// Reset POI Detector Allowed Loopback ...
provider.MaxAllowedLoopbackForInit(578);
//
// Check Working Zone Has Trend ...
hasTrend = workingZone.DetectTreand(
X_CYCLE_CONSOLIDATION,
trend,
provider,
zIndex //
);
//
// Detectiong Signal Boxes ...
hasWaitingBoxes = workingZone
.DetectWaitingBoxes(
X_CYCLE_ANALYSE,
X_CYCLE_DECISION,
provider,
zIndex //
);
if (hasWaitingBoxes)
{
//
// Validate Working Zone Waiting Boxes ...
workingZone.ValidateWaitingBoxes(zIndex);
//
// Double Check Has Waiting Boxes or not ...
hasWaitingBoxes = workingZone.HasWaitingBoxes();
}
//
// Checking Working Zone Destory or not ...
bool isWorkingZoneDestroyed = workingZone.IsDestroyed(
zIndex,
period //
);
//
// Cleanup WorkingZone and ignore all conditions ...
if (isWorkingZoneDestroyed)
{
//
result = false;
workingZone.Clean();
hasWorkingZone = false;
//
// Cleanup Resources ...
provider.Clean();
//
mConditions.Clean();
consolidationZBar.Clean();
//
return result;
}
}
//
// Update Models To Time ...
UpdateTo(cTime);
//
// Draw Working Zone ...
workingZone.Draw(
drawer,
//
false, // Draw Supply Zone ...
false, // Draw Demand Zone ...
true, // Draw Waiting Zones ...
false // Draw Trend ...
);
//
// Detect Signal Box ...
hasSignalBox =
hasWorkingZone &&
workingZone.DetectSignalConditions(
signalBox,
signalBoxDir,
signalProvider,
provider,
zIndex //
);
//
// Remove Signal Box form
// Waiting Boxes and Breaked Boxes
// if Exists on them, then add it to
// UnAvailable Boxes ...
if (hasSignalBox)
{
//
// Remove Signal Box from UnAvailable Box ...
// if Exists ...
bool hasBreakedBoxes = workingZone
.HasBreakedBoxes();
if (hasBreakedBoxes)
{
//
int idx = -1;
bool has = FindIndex(
idx,
signalBox,
workingZone.breakedBoxes //
);
if (has)
{
//
ArrayRemove(
workingZone.breakedBoxes,
idx,
1 //
);
}
}
//
// Add Signal Box to UnAvailable Boxes ...
// if Exists in Waiting Boxes ...
if (hasWaitingBoxes)
{
//
int idx = -1;
bool has = FindIndex(
idx,
signalBox,
workingZone.waitingBoxes //
);
if (has)
{
//
ArrayRemove(
workingZone.waitingBoxes,
idx,
1 //
);
}
}
//
// Adding to UnAvailable Box ...
AddRef(
signalBox,
workingZone.unavailableBoxes //
);
}
//
//
//
//
// Cleanup Signal if UnApproved ...
if (!hasSignalBox)
{
//
signalBox.Clean();
signalBoxDir = X_DIRECTION_NONE;
}
//
// Check Priority Exists ...
hasPriority =
hasWorkingZone &&
workingZone
.DetectPriority(
priority,
signalBoxDir,
zIndex,
period //
);
//
// Check Price Reward and Amount Exists ...
hasRewardAmount =
hasWorkingZone &&
CalculateRiskReward(
priority,
reward,
amountPercent //
);
//
// Check Signal Conditions ...
if (hasSignalBox)
{
//
int idx = -1;
bool has = false;
//
// Draw Signal Box ...
XCBaseObject *objects[];
has = drawer.DrawSignalBox(
signalBox,
objects,
clrYellow //
);
if (has)
{
//
int count = ArraySize(objects);
for (int i = 0; i < count; i++)
{
workingZone.mDrawnObjects.Add(objects[i]);
}
}
Clean(objects);
//
// Detect Signal Direction ...
isBullish = IsBullish(signalBoxDir);
isBearish = IsBearish(signalBoxDir);
//
pivot = isBullish
? signalBox.ob.lower
: signalBox.ob.upper;
//
point = isBullish
? signalBox.ob.upper
: signalBox.ob.lower;
//
double entry = GetEntry(
signalBox.ob.symbol,
signalBoxDir //
);
//
// Selecting SL(s) ...
//
double iSL = 0;
//
// Default SL ...
iSL = pivot;
//
Add(
iSL,
sls //
);
//
// Select and Provide SL Based on ...
double iAtr = 0;
if (signalProvider == X121SMC_XWZ_PROVIDER_XREJECTED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
// Fix rf Reward ...
rfRewar = 2;
}
else if (signalProvider == X121SMC_XWZ_PROVIDER_XACTIVATED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
Clean(sls);
//
// Prepare Box fro SL ...
iSL = pivot;
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
else if (signalProvider == X121SMC_XWZ_PROVIDER_XBREAKED_BOX)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0;
//
Clean(sls);
//
// Prepare Box fro SL ...
iSL = pivot;
Add(
iSL,
sls //
);
//
// Fix rf Reward ...
rfRewar = 2;
}
//
Print("XWZ ", ToString(signalBoxDir), " Signal Provided: ", EnumToString(signalProvider));
//
// Select Condition SL ...
//
double slsMin = GetMin(sls);
double slsMax = GetMax(sls);
//
double longSL = slsMax - iAtr;
double shortSL = slsMin + iAtr;
//
sl = isBullish
? longSL
: shortSL;
//
// Targets ...
//
double risk = MathAbs(entry - sl);
//
// Checking risk ...
if (risk >= maxAllowedSLDistanceInPoint)
{
// Print("Max Aloowed Risk Point Reached ...");
}
//
// Reward to RF ...
if (rfRewar > 0)
{
//
double iRFReward = rfRewar * risk;
double iRFTP = isBullish
? entry + iRFReward
: entry - iRFReward;
//
Add(
iRFTP,
targets //
);
}
//
// Based On Priority ...
useQuarterTargets = false;
if (useQuarterTargets)
{
//
has = priority != X121SMC_XWZ_PRIORITY_NONE;
if (has)
{
//
switch (priority)
{
//
case X121SMC_XWZ_PRIORITY_WEAK:
//
if (isBullish)
{
//
// Weak ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
}
else
{
//
// Weak ...
Add(
workingZone.demandZone.Upper(),
targets //
);
}
break;
//
case X121SMC_XWZ_PRIORITY_LOW:
//
if (isBullish)
{
//
// Weak ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
//
// Low ...
Add(
workingZone.quarter1,
targets //
);
}
else
{
//
// Weak ...
Add(
workingZone.demandZone.Upper(),
targets //
);
//
// Low ...
Add(
workingZone.quarter3,
targets //
);
}
break;
//
case X121SMC_XWZ_PRIORITY_REGULAR:
//
if (isBullish)
{
//
// Weak ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
//
// Low ...
Add(
workingZone.quarter1,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
}
else
{
//
// Weak ...
Add(
workingZone.demandZone.Upper(),
targets //
);
//
// Low ...
Add(
workingZone.quarter3,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
}
break;
//
case X121SMC_XWZ_PRIORITY_HIGH:
//
if (isBullish)
{
//
// Weak ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
//
// Low ...
Add(
workingZone.quarter1,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
//
// High ...
Add(
workingZone.quarter3,
targets //
);
}
else
{
//
// Weak ...
Add(
workingZone.demandZone.Upper(),
targets //
);
//
// Low ...
Add(
workingZone.quarter3,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
//
// High ...
Add(
workingZone.quarter1,
targets //
);
}
break;
//
case X121SMC_XWZ_PRIORITY_STRONG_HIGH:
//
if (isBullish)
{
//
// Weak ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
//
// Low ...
Add(
workingZone.quarter1,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
//
// High ...
Add(
workingZone.quarter3,
targets //
);
//
// Strong High ...
Add(
workingZone.demandZone.Upper(),
targets //
);
}
else
{
//
// Weak ...
Add(
workingZone.demandZone.Upper(),
targets //
);
//
// Low ...
Add(
workingZone.quarter3,
targets //
);
//
// Regular ...
Add(
workingZone.quarter2,
targets //
);
//
// High ...
Add(
workingZone.quarter1,
targets //
);
//
// Strong High ...
Add(
workingZone.supplyZone.Lower(),
targets //
);
}
break;
}
}
}
}
//
// Summarize Results ...
result = hasPriority &&
hasSignalBox &&
hasRewardAmount;
//
if (result)
{
//
Copy(
sls,
mConditions.sls //
);
Copy(
targets,
mConditions.targets //
);
//
mConditions.sl = sl;
mConditions.pivot = pivot;
mConditions.point = point;
mConditions.reward = reward;
mConditions.setupTime = cTime;
mConditions.dir = signalBoxDir;
mConditions.priority = priority;
mConditions.signalBox = signalBox.ob;
mConditions.provider = signalProvider;
mConditions.amountPercent = amountPercent;
}
//
//
//
//
// Cleanup Resources ...
//
Clean(sls);
Clean(targets);
//
provider.Clean();
//
signalBox.Clean();
consolidationZBar.Clean();
//
return result;
}
//
// Detect Trigger Conditions ...
bool DetectSignalTrigger(
//
X121SMCStrategyXWZSignalConditions &conditions,
//
X121SMCStrategySignalProviderData &provider,
//
int maxAllowedSetupAge = 60
//
)
{
//
bool result = false;
//
result =
//
provider.IsValid()
//
;
if (!result)
{
return result;
}
//
result = conditions.IsSetuped();
if (!result)
{
return result;
}
//
datetime setupTime = conditions.setupTime;
ENUM_X_DIRECTION setupDir = conditions.dir;
//
bool isBullish = IsBullish(setupDir);
bool isBearish = IsBearish(setupDir);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
// Cycles Conditions ...
result = provider.Prepare(
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
double iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 1.5;
//
// Check Signal Validation ...
// IMPORTANT: since all Validations done in SetUp Process ...
// here we only Execute Signal ...
//
result = isBullish ||
isBearish;
//
if (result)
{
//
conditions.triggerTime = cTime;
conditions.type = isBullish
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
}
//
// Cleanup ...
//
provider.Clean();
//
return result;
}
//
// Detect Guards ...
bool DetectGuards(
//
X121SMCGuard &guards[],
const XPosition &positions[],
//
X121SMCStrategySignalProviderData &provider
//
)
{
//
bool result = false;
//
if (!useGuards)
{
return result;
}
//
Clean(guards);
//
// Set Provider for Common Guards ...
string signalProvider = ToString(X_121_SMC_PROVIDER_XWZ);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
XOHCL cBar;
//
int loopback = 10;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
// Cycles Conditions ...
result = provider.IsValid();
result =
result &&
provider.Prepare(
zIndex,
loopback //
);
if (!result)
{
//
provider.Clean();
return result;
}
//
// Select Own Positions ...
int count = ArraySize(positions);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
XPosition ownPositions[];
XPosition ownLongPositions[];
XPosition ownShortPositions[];
for (int i = 0; i < count; i++)
{
//
XPosition iPosition = positions[i];
bool isOwn = iPosition
.IsFiltersPassed(
symbol,
signalProvider,
NULL,
X_POSITION_TYPE_ALL,
iPosition.magic //
);
if (isOwn)
{
//
AddRef(
iPosition,
ownPositions //
);
//
bool isLong = IsLong(positions[i].type);
if (isLong)
{
//
AddRef(
iPosition,
ownLongPositions //
);
}
else
{
//
AddRef(
iPosition,
ownShortPositions //
);
}
}
}
//
// Check Extracted Positions ...
//
count = ArraySize(ownPositions);
//
int longsCount = ArraySize(ownLongPositions);
bool hasLongs = IsValidSize(longsCount);
//
int shortsCount = ArraySize(ownShortPositions);
bool hasShorts = IsValidSize(shortsCount);
//
// Validate Own Positions ...
result = IsValidSize(count);
if (!result)
{
//
Clean(ownPositions);
Clean(ownLongPositions);
Clean(ownShortPositions);
//
return result;
}
//
//
//
//
// Get Global and Common Guards ...
//
// ENUM_X_121_SMC_GUARD_ACTIONS ignoreGuards[1] = {
// X_121_SMC_GUARD_ACTION_TRAIL_STOP //
// };
// result = DetectX121SMCGuards(
// signalProvider,
// guards,
// positions,
// provider,
// //
// ignoreGuards
// //
// );
//
//
//
//
// Implement Custom Implemented Guards ...
//
// Here we Are Sure there is Positions to Guard ...
// based on Current Provider ...
//
// Selected Consolidation Zones ...
//
int idx = -1;
bool has = false;
//
bool hasBullishConsolidationZone = false;
XConsolidationZone bullishConsolidationZone;
has = provider.decisionState.HasBullishConsolidationZones();
if (has)
{
//
idx = GetYoungest(provider.decisionState.bullishConsolidationZones);
hasBullishConsolidationZone = IsValidIndex(idx);
if (hasBullishConsolidationZone)
{
bullishConsolidationZone = provider.decisionState.bullishConsolidationZones[idx];
}
}
//
bool hasBearishConsolidationZone = false;
XConsolidationZone bearishConsolidationZone;
has = provider.decisionState.HasBearishConsolidationZones();
if (has)
{
//
idx = GetYoungest(provider.decisionState.bearishConsolidationZones);
hasBearishConsolidationZone = IsValidIndex(idx);
if (hasBearishConsolidationZone)
{
bearishConsolidationZone = provider.decisionState.bearishConsolidationZones[idx];
}
}
//
XBoxZone bullishBox;
bool hasBullishBox = false;
bool isBullishBoxBreaked = false;
if (!hasBullishBox)
{
//
XCOrderBlock *ob = NULL;
idx = GetYoungest(provider.analyseState.bullishOrderBlocks);
has = IsValidIndex(idx);
if (has)
{
//
ob = provider.analyseState.bullishOrderBlocks[idx];
//
hasBullishBox = ToBox(
bullishBox,
ob //
);
}
//
if (!hasBullishBox)
{
bullishBox.Clean();
}
//
ZeroMemory(ob);
}
//
XBoxZone bearishBox;
bool hasBearishBox = false;
bool isBearishBoxBreaked = false;
if (!hasBearishBox)
{
//
XCOrderBlock *ob = NULL;
idx = GetYoungest(provider.analyseState.bearishOrderBlocks);
has = IsValidIndex(idx);
if (has)
{
//
ob = provider.analyseState.bearishOrderBlocks[idx];
//
hasBearishBox = ToBox(
bearishBox,
ob //
);
}
//
if (!hasBearishBox)
{
bearishBox.Clean();
}
//
ZeroMemory(ob);
}
//
// Here We Have all Requirements for Guarding Positions ...
//
// Available Guards:
// X_121_SMC_GUARD_ACTION_NONE
// X_121_SMC_GUARD_ACTION_CLOSE
// X_121_SMC_GUARD_ACTION_CLOSE_ALL
// X_121_SMC_GUARD_ACTION_CLOSE_LONGS
// X_121_SMC_GUARD_ACTION_CLOSE_SHORTS
// X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE
// X_121_SMC_GUARD_ACTION_TRAIL_STOP
// X_121_SMC_GUARD_ACTION_TRAIL_TARGET
// X_121_SMC_GUARD_ACTION_HEDGE
//
// X_121_SMC_GUARD_ACTION_CLOSE:
// Close Specified Position on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_CLOSE_ALL:
// Close All Positions on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_CLOSE_LONGS:
// Close All Long Positions on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_CLOSE_SHORTS:
// Close All Short Positions on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE:
// Partial Close Specified Position on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_TRAIL_STOP:
// Trail Stop Specified Position on Specified Conditions ...
bool handleStoptrailingBasedOnBoxes = true;
bool handleStoptrailingBasedOnConsolidationZones = true;
for (int i = 0; i < count; i++)
{
//
XPosition iPosition = ownPositions[i];
//
bool isInited = cBar.Init(
iPosition.symbol,
iPosition.period,
cIndex //
);
//
isBullishBoxBreaked =
isInited &&
hasBullishBox &&
cBar.high < bullishBox.lower;
//
isBearishBoxBreaked =
isInited &&
hasBearishBox &&
cBar.low > bearishBox.upper;
//
bool isLong = IsLong(iPosition.type);
bool isInProfit = iPosition.profit > 0;
//
double sl = iPosition.sl;
double tp = iPosition.tp;
//
// Trail Stops Using Consolidation Zones ...
//
bool canTraiLonglUsingCZone =
//
handleStoptrailingBasedOnConsolidationZones &&
//
(isLong &&
isInProfit &&
hasBullishConsolidationZone &&
bullishConsolidationZone.lower > iPosition.sl &&
bullishConsolidationZone.lower > iPosition.entry)
//
;
if (canTraiLonglUsingCZone)
{
sl = bullishConsolidationZone.lower;
}
//
bool canTraiShortlUsingCZone =
//
handleStoptrailingBasedOnConsolidationZones &&
//
(!isLong &&
isInProfit &&
hasBearishConsolidationZone &&
bearishConsolidationZone.upper < iPosition.sl &&
bearishConsolidationZone.upper < iPosition.entry)
//
;
if (canTraiShortlUsingCZone)
{
sl = bearishConsolidationZone.upper;
}
//
bool canTrailUsingCZone =
canTraiLonglUsingCZone ||
canTraiShortlUsingCZone;
//
// Trail Stop Using Boxes ...
//
bool canTraiLonglUsingBox =
//
handleStoptrailingBasedOnBoxes &&
//
(isLong &&
isInProfit &&
hasBullishBox &&
bullishBox.lower > iPosition.sl &&
bullishBox.lower > iPosition.entry)
//
;
if (canTraiLonglUsingBox)
{
sl = bullishBox.lower;
}
//
bool canTraiShortlUsingBox =
//
handleStoptrailingBasedOnBoxes &&
//
(!isLong &&
isInProfit &&
hasBearishBox &&
bearishBox.upper < iPosition.sl &&
bearishBox.upper < iPosition.entry)
//
;
if (canTraiShortlUsingBox)
{
sl = bearishBox.upper;
}
//
bool canTrailUsingBox =
canTraiLonglUsingBox ||
canTraiShortlUsingBox;
//
bool canTraiLonglUsingBreakedBox =
//
handleStoptrailingBasedOnBoxes &&
//
(isLong &&
isInProfit &&
isBearishBoxBreaked &&
bearishBox.upper > iPosition.sl &&
bearishBox.upper > iPosition.entry)
//
;
if (canTraiLonglUsingBreakedBox)
{
sl = bearishBox.upper;
}
//
bool canTraiShortlUsingBreakedBox =
//
handleStoptrailingBasedOnBoxes &&
//
(!isLong &&
isInProfit &&
isBullishBoxBreaked &&
bullishBox.lower < iPosition.sl &&
bullishBox.lower < iPosition.entry)
//
;
if (canTraiShortlUsingBreakedBox)
{
sl = bullishBox.lower;
}
//
bool canTrailUsingBreakedBox =
canTraiLonglUsingBreakedBox ||
canTraiShortlUsingBreakedBox;
//
// Summarize SL ...
//
bool isSLPassed =
sl > 0 &&
(isLong
? iPosition.price - sl >= points * 15
: sl - iPosition.price >= points * 15);
//
bool canTrail =
isSLPassed &&
(canTrailUsingBox ||
canTrailUsingCZone ||
canTrailUsingBreakedBox);
if (canTrail)
{
//
X121SMCGuard iGuard;
//
iGuard.time = cTime;
iGuard.symbol = symbol;
iGuard.provider = signalProvider;
iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP;
//
iGuard.ticket = iPosition.ticket;
//
iGuard.sl = sl;
//
AddGuard(
iGuard,
guards //
);
}
}
//
// X_121_SMC_GUARD_ACTION_TRAIL_TARGET:
// Trail Target Specified Position on Specified Conditions ...
//
// X_121_SMC_GUARD_ACTION_HEDGE:
// Hedge all Positions on Specified Conditions ...
//
// Cleanup Collections ...
//
cBar.Clean();
//
provider.Clean();
//
bullishBox.Clean();
bearishBox.Clean();
//
bullishConsolidationZone.Clean();
bearishConsolidationZone.Clean();
//
count = ArraySize(guards);
result = IsValidSize(count);
//
return result;
}
//
// Add Conditions to Conditions Collection ...
int AddConditionsIfNotExists(
int maxAllowed = 10 //
)
{
//
int result = 0;
//
bool isSetuped = IsValid(mConditions.setupTime) &&
HasDirection(mConditions.dir);
if (!isSetuped)
{
return result;
}
//
int count = ArraySize(mConditionsCollection);
if (IsValidSize(count))
{
//
// Copy Original Items ...
X121SMCStrategyXWZSignalConditions tmpItems[];
Copy(
mConditionsCollection,
tmpItems //
);
//
// Prese Item Data ...
bool isBullish = IsBullish(mConditions.dir);
//
for (int i = 0; i < count; i++)
{
//
X121SMCStrategyXWZSignalConditions iItem = tmpItems[i];
//
bool canRemove = mConditions.dir == iItem.dir &&
mConditions.pivot == iItem.pivot;
if (canRemove)
{
//
ArrayRemove(
mConditionsCollection,
i,
1 //
);
}
}
//
Clean(tmpItems);
}
//
AddRef(
mConditions,
mConditionsCollection //
);
//
// Remove Olds ...
CleanupArray(
mConditionsCollection,
maxAllowed //
);
//
result = ArraySize(mConditionsCollection);
//
return result;
}
//
// Draw Functions ...
//
//
void DrawBar(
XOHCL &bar,
XCPOIDrawer *drawer,
bool forceClean = true //
)
{
//
if (forceClean)
{
mBarObjects.Clear();
}
//
if (drawer == NULL ||
!bar.IsValid())
{
return;
}
//
bool isBullish = bar.IsBullish();
//
int widthBar = 2;
bool fillShadowsBar = true;
ENUM_LINE_STYLE styleBar = STYLE_SOLID;
color clrBar =
isBullish
? clrAqua
: clrMagenta;
//
datetime to = bar.NextAt();
//
XCOHCLObject *iObj;
bool isCreated = drawer
.CreateBar(
bar,
iObj,
to //
);
if (isCreated)
{
//
iObj.BarSpes(
widthBar,
clrBar,
styleBar //
);
//
iObj.LowShadowFill(fillShadowsBar);
iObj.HighShadowFill(fillShadowsBar);
//
mBarObjects.Add(iObj);
}
}
//
protected:
//
//
private:
//
// Props ...
string symbol;
ENUM_TIMEFRAMES period;
CArrayObj mObjects;
CArrayObj mBarObjects;
CArrayObj mWorkingZoneObjects;
/**
* Initialize ...
*/
void Init()
{
//
rfRewar = 2;
useGuards = false;
useQuarterTargets = false;
}
/**
* DeInitialize ...
*/
void DeInit()
{
//
mConditions.Clean();
workingZone.Clean();
Clean(mConditionsCollection);
//
mBarObjects.Clear();
}
/**
* Update To Time of Exists Components ...
*
* @param value: updated time ...
*/
void UpdateTo(
datetime value = NULL //
)
{
//
value = NormalizeTime(value);
//
workingZone.UpdateTo(value);
}
//
// Helpers ...
//
bool CalculateRiskReward(
ENUM_X121SMC_XWZ_PRIORITY priority,
double &reward,
double &amountPercent //
)
{
//
bool result = false;
//
reward = 0;
amountPercent = 0;
//
result = priority != X121SMC_XWZ_PRIORITY_NONE;
if (!result)
{
return result;
}
//
switch (priority)
{
//
case X121SMC_XWZ_PRIORITY_STRONG_HIGH:
//
reward = 6;
amountPercent = 2;
break;
//
case X121SMC_XWZ_PRIORITY_HIGH:
//
reward = 4;
amountPercent = 2;
break;
//
case X121SMC_XWZ_PRIORITY_REGULAR:
//
reward = 3;
amountPercent = 1.5;
break;
//
case X121SMC_XWZ_PRIORITY_LOW:
//
reward = 2;
amountPercent = 1;
break;
//
case X121SMC_XWZ_PRIORITY_WEAK:
//
reward = 1;
amountPercent = 0.5;
break;
}
//
result =
//
reward > 0 &&
amountPercent > 0
//
;
//
return result;
}
//
};
//