Files
MQL5Data/X121SMCEA/Signals/x-121.smc.xind.signal.class.mq5
T

1930 lines
45 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121 SMC Signal Class
// -------------------------------------------------
// Name: XICH
// 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.xind.signal.lib.mq5"
//
// Definition ...
class XCX121SMCXINDSignalDetector : public XCBase
{
//
public:
//
// Props ...
bool useGuards;
double rfRewar;
XBoxZone mWaitingBoxes[];
XBoxZone mBreakedBoxes[];
XBoxZone mActivatedBoxes[];
XBoxZone mUnAvailableBoxes[];
X121SMCStrategyXINDSignalConditions mConditions;
X121SMCStrategyXINDSignalConditions mConditionsCollection[];
//
// Constructor(s) ...
XCX121SMCXINDSignalDetector(
string _symbol,
ENUM_TIMEFRAMES _period //
)
{
//
symbol = _symbol;
period = _period;
Init();
}
//
// Deconstructor ...
~XCX121SMCXINDSignalDetector()
{
DeInit();
}
//
//
//
/**
* Detect Setup Conditions based on Signalling ...
*
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
* @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ...
*
* @return ( bool )
*/
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;
//
int idx = -1;
int count = 0;
bool has = false;
//
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,
true, // 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;
//
// Detecting Bars based on Decision Cycle ...
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL pPBar;
XOHCL consolidationZBar;
result = zBar.Init(
provider.decisionXConditions.symbol,
provider.decisionXConditions.period,
zIndex //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
result =
result &&
pBar.GetPreviousBar(pPBar);
result =
result &&
provider.consolidationCycleHelper.GetBar(
consolidationZBar,
zIndex //
);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
pPBar.Clean();
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[];
XBoxZone signalBox;
bool hasSignalBox = false;
ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE;
ENUM_X121SMC_XIND_PROVIDERS signalProvider = X121SMC_XIND_PROVIDER_NONE;
//
//
//
//
int waitingBoxesCount = UpdateWaitingBoxes(
X_CYCLE_DECISION,
provider //
);
bool hasWaitingBoxes = IsValidSize(waitingBoxesCount);
//
DrawBoxes(drawer);
//
if (hasWaitingBoxes)
{
//
hasSignalBox = HasXPVConditions(
mWaitingBoxes,
mActivatedBoxes,
mBreakedBoxes,
X_CYCLE_DECISION,
signalBox,
signalBoxDir,
provider,
zIndex //
);
if (hasSignalBox)
{
//
signalProvider = X121SMC_XIND_PROVIDER_XSTR;
//
MakeSignalBoxUnAvailable(signalBox);
}
}
//
//
//
//
// Cleanup Signal if UnApproved ...
if (!hasSignalBox)
{
//
signalBox.Clean();
isBullish = false;
isBearish = false;
signalBoxDir = X_DIRECTION_NONE;
}
//
// Summarize Results ...
result = hasSignalBox;
//
if (result)
{
//
int idx = -1;
bool has = false;
//
// Draw Signal Box ...
XCBoxObject *object;
has = drawer.DrawBox(
signalBox,
object //
);
if (has)
{
mObjects.Add(object);
}
//
// Detect Signal Direction ...
isBullish = IsBullish(signalBoxDir);
isBearish = IsBearish(signalBoxDir);
//
pivot = isBullish
? signalBox.lower
: signalBox.upper;
//
point = isBullish
? signalBox.upper
: signalBox.lower;
//
double entry = GetEntry(
signalBox.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_XIND_PROVIDER_XSTR)
{
//
iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 0.5;
//
// Fix rf Reward ...
rfRewar = 2;
}
//
// 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 //
);
}
//
Copy(
sls,
mConditions.sls //
);
Copy(
targets,
mConditions.targets //
);
//
mConditions.sl = sl;
mConditions.pivot = pivot;
mConditions.point = point;
mConditions.setupTime = cTime;
mConditions.dir = signalBoxDir;
mConditions.signalBox = signalBox;
mConditions.provider = signalProvider;
}
//
//
//
//
// Cleanup Resources ...
//
Clean(sls);
Clean(targets);
//
provider.Clean();
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
pPBar.Clean();
signalBox.Clean();
ZeroMemory(drawer);
consolidationZBar.Clean();
//
return result;
}
/**
* Detect Trigger Conditions for Specified Signal ...
*
* @param conditions: X121SMCStrategyXINDSignalConditions instance Reference, Specified Signal Conditions ...
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
* @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ...
*
* @return ( bool )
*/
bool DetectSignalTrigger(
X121SMCStrategyXINDSignalConditions &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 bsed on Signalling Class ...
*
* @param guards: X121SMCGuard instance Collection, Holds Provided Guards ...
* @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ...
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
*
* @return ( bool )
*/
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(X121SMC_XIND_PROVIDER_XTKKUMO);
//
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;
}
/**
* Detect and Manage Important Zones and Categorized them for Signalling Clss ...
*
* @param cycle: ENUM_X_CYCLES member, Specified Source Cycle for Detecting ...
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
*
* @return ( int )
*/
int UpdateWaitingBoxes(
ENUM_X_CYCLES cycle,
X121SMCStrategySignalProviderData &provider //
)
{
//
int result = ArraySize(mWaitingBoxes) + ArraySize(mActivatedBoxes);
//
int count = 0;
bool has = false;
//
// Fil Selected Data ...
XPOIState cState;
X121Conditions cXConditions;
XPOIStateEvents cStateEvents;
XC121SMCCycleHelper *cHelper;
X121SMCCycleConditions cConditions;
has = provider.SelectCycle(
cycle,
cState,
cStateEvents,
cXConditions,
cHelper,
cConditions //
);
if (!has)
{
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
cStateEvents.Clean();
//
return result;
}
//
// Detecting New Boxes ...
//
// Checking Bullish Fair Value Gaps ...
has = cState.HasBullishFairValueGaps();
if (has)
{
//
XBoxZone tmpBoxes[];
ToBox(
cState.bullishFairValueGaps,
tmpBoxes //
);
//
count = ArraySize(tmpBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
bool isValid = IsBoxValid(
iBox,
0,
iBox.period //
);
if (!isValid)
{
//
iBox.Clean();
continue;
}
//
has = IsBoxExists(iBox);
if (!has)
{
//
AddRef(
iBox,
mWaitingBoxes //
);
}
//
iBox.Clean();
}
}
//
Clean(tmpBoxes);
}
//
// Checking Bearish Fair Value Gaps ...
has = cState.HasBearishFairValueGaps();
if (has)
{
//
XBoxZone tmpBoxes[];
ToBox(
cState.bearishFairValueGaps,
tmpBoxes //
);
//
count = ArraySize(tmpBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
bool isValid = IsBoxValid(
iBox,
0,
iBox.period //
);
if (!isValid)
{
//
iBox.Clean();
continue;
;
}
//
has = IsBoxExists(iBox);
if (!has)
{
//
AddRef(
iBox,
mWaitingBoxes //
);
}
//
iBox.Clean();
}
}
//
Clean(tmpBoxes);
}
//
// Update Times ...
datetime requireTime = GetBarTime(
cState.symbol,
cState.period,
1 //
);
//
count = ArraySize(mWaitingBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
mWaitingBoxes[i].to = requireTime;
}
}
//
count = ArraySize(mActivatedBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
mActivatedBoxes[i].to = requireTime;
}
}
//
// Validate Exists Boxes ...
//
// Waiting Boxes ...
count = ArraySize(mWaitingBoxes);
has = IsValidSize(count);
if (has)
{
//
int mustRemove[];
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = mWaitingBoxes[i];
//
// Check Box Validation ...
bool isValid = IsBoxValid(
iBox,
0,
iBox.period //
);
//
// Check Box Breaked ...
bool isBreaked = IsBoxBreaked(
iBox,
0,
iBox.period //
);
//
// Box Waiting ...
if (isValid)
{
//
iBox.Clean();
continue;
}
//
// Box Breaked ...
if (isBreaked)
{
//
Add(
i,
mustRemove //
);
//
AddRef(
iBox,
mBreakedBoxes //
);
//
iBox.Clean();
continue;
}
//
// Box Activated ...
if (!isValid)
{
//
Add(
i,
mustRemove //
);
//
AddRef(
iBox,
mActivatedBoxes //
);
//
iBox.Clean();
continue;
}
//
iBox.Clean();
}
//
CleanupArray(
mustRemove,
mWaitingBoxes //
);
}
//
// Activated Boxes ...
count = ArraySize(mActivatedBoxes);
has = IsValidSize(count);
if (has)
{
//
int mustRemove[];
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = mActivatedBoxes[i];
//
// Check Breaked ...
bool isBreaked = IsBoxBreaked(
iBox,
0,
iBox.period //
);
if (isBreaked)
{
//
Add(
i,
mustRemove //
);
//
AddRef(
iBox,
mBreakedBoxes //
);
//
iBox.Clean();
continue;
}
//
iBox.Clean();
}
//
CleanupArray(
mustRemove,
mActivatedBoxes //
);
}
//
// Cleanup Resources ...
//
cState.Clean();
ZeroMemory(cHelper);
cConditions.Clean();
cXConditions.Clean();
cStateEvents.Clean();
//
result = ArraySize(mWaitingBoxes) + ArraySize(mActivatedBoxes);
//
return result;
}
/**
* Make a Detected Signal Box UnAvailable for Prevent of Double Executing ...
*
* @param box: XBoxZone instance Reference, Specified Signal Box ...
*/
void MakeSignalBoxUnAvailable(
XBoxZone &box //
)
{
//
int idx = -1;
int count = 0;
bool has = false;
//
// Validate Box ...
has = box.IsValid();
if (!has)
{
return;
}
//
// Check Waiting Boxes ...
count = ArraySize(mWaitingBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mWaitingBoxes //
);
if (has)
{
//
// Remove Signal Box From Collection ...
ArrayRemove(
mWaitingBoxes,
idx,
1 //
);
//
// Add Signal Box to UnAvailable Boxes ...
AddRef(
box,
mUnAvailableBoxes //
);
//
return;
}
}
//
// Check Activated Boxes ...
count = ArraySize(mActivatedBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mActivatedBoxes //
);
if (has)
{
//
// Remove Signal Box From Collection ...
ArrayRemove(
mActivatedBoxes,
idx,
1 //
);
//
// Add Signal Box to UnAvailable Boxes ...
AddRef(
box,
mUnAvailableBoxes //
);
//
return;
}
}
//
// Check Breaked Boxes ...
count = ArraySize(mBreakedBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mBreakedBoxes //
);
if (has)
{
//
// Remove Signal Box From Collection ...
ArrayRemove(
mBreakedBoxes,
idx,
1 //
);
//
// Add Signal Box to UnAvailable Boxes ...
AddRef(
box,
mUnAvailableBoxes //
);
//
return;
}
}
}
/**
* Check a Box is Exists in Box Collections of Signalling Collections ...
*
* @param box: XBoxZone instance Reference, Specified Box to Check ...
*
* @return ( bool )
*/
bool IsBoxExists(XBoxZone &box)
{
//
bool result = false;
//
int idx = -1;
int count = 0;
bool has = false;
//
// Witing Boxes ...
count = ArraySize(mWaitingBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mWaitingBoxes //
);
result = has;
if (result)
{
return result;
}
}
//
// Activated Boxes ...
count = ArraySize(mActivatedBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mActivatedBoxes //
);
result = has;
if (result)
{
return result;
}
}
//
// Breaked Boxes ...
count = ArraySize(mBreakedBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mBreakedBoxes //
);
result = has;
if (result)
{
return result;
}
}
//
// UnAvailable Boxes ...
count = ArraySize(mUnAvailableBoxes);
has = IsValidSize(count);
if (has)
{
//
has = FindBoxIndex(
idx,
box,
mUnAvailableBoxes //
);
result = has;
if (result)
{
return result;
}
}
//
return result;
}
/**
* Add Conditions to Conditions Collection if not Exists ...
*
* @param maxAllowed: int, Specified Max Allowed Holding Conditions ...
*
* @return ( int )
*/
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 ...
X121SMCStrategyXINDSignalConditions tmpItems[];
Copy(
mConditionsCollection,
tmpItems //
);
//
// Prese Item Data ...
bool isBullish = IsBullish(mConditions.dir);
//
for (int i = 0; i < count; i++)
{
//
X121SMCStrategyXINDSignalConditions 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 ...
/**
* Draw Specified Bar on Chart ...
*
* @param bar: XOHCL instance Reference, Specified Bar ...
* @param forceClean: force Clean Drawn Objects ...
*/
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);
}
}
/**
* Draw Boxes of Signallings on Chart ...
*
* @param forceClean: force Clean Drawn Objects ...
*/
void DrawBoxes(
XCPOIDrawer *drawer,
bool forceClean = false //
)
{
//
if (forceClean)
{
mObjects.Clear();
}
//
int count = 0;
bool has = false;
//
// Waiting Boxes ...
count = ArraySize(mWaitingBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCBoxObject *iObj;
has = drawer.DrawBox(
mWaitingBoxes[i],
iObj //
);
if (has)
{
mObjects.Add(iObj);
}
}
}
//
// Activated Boxes ...
count = ArraySize(mActivatedBoxes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCBoxObject *iObj;
has = drawer.DrawBox(
mActivatedBoxes[i],
iObj //
);
if (has)
{
//
if (mActivatedBoxes[i].IsBullish())
{
iObj.BoxColor(clrYellow);
}
else
{
iObj.BoxColor(clrOrange);
}
//
mObjects.Add(iObj);
}
}
}
}
//
protected:
//
//
private:
//
// Props ...
string symbol;
ENUM_TIMEFRAMES period;
CArrayObj mObjects;
CArrayObj mBarObjects;
/**
* Initialize ...
*/
void Init()
{
//
rfRewar = 2;
useGuards = false;
}
/**
* DeInitialize ...
*/
void DeInit()
{
//
mConditions.Clean();
Clean(mConditionsCollection);
//
mObjects.Clear();
mBarObjects.Clear();
}
//
};
//