1252 lines
29 KiB
Plaintext
1252 lines
29 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.xich.signal.lib.mq5"
|
|
|
|
//
|
|
// Definition ...
|
|
class XCX121SMCXICHSignalDetector : public XCBase
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
// Props ...
|
|
bool useGuards;
|
|
double rfRewar;
|
|
X121SMCStrategyXICHSignalConditions mConditions;
|
|
X121SMCStrategyXICHSignalConditions mConditionsCollection[];
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XCX121SMCXICHSignalDetector(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period //
|
|
)
|
|
{
|
|
//
|
|
symbol = _symbol;
|
|
period = _period;
|
|
Init();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCX121SMCXICHSignalDetector()
|
|
{
|
|
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,
|
|
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_XICH_PROVIDERS signalProvider = X121SMC_XICH_PROVIDER_NONE;
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Provider XTkKumo ...
|
|
X121SMCStrategyConditionParser cParser;
|
|
hasSignalBox = cParser.HasXICHConditions(
|
|
X_CYCLE_ANALYSE,
|
|
signalBox,
|
|
signalBoxDir,
|
|
provider,
|
|
zIndex //
|
|
);
|
|
if (hasSignalBox)
|
|
{
|
|
signalProvider = X121SMC_XICH_PROVIDER_XTKKUMO;
|
|
}
|
|
|
|
//
|
|
// Update Models To Time ...
|
|
UpdateTo(cTime);
|
|
|
|
//
|
|
// 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_XICH_PROVIDER_XTKKUMO)
|
|
{
|
|
//
|
|
iAtr = provider.decisionXConditions.atrBuffer[1];
|
|
iAtr *= 0;
|
|
|
|
//
|
|
// Fix rf Reward ...
|
|
rfRewar = 1.5;
|
|
}
|
|
|
|
//
|
|
Print("XICH ", 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 //
|
|
);
|
|
}
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
cParser.Clean();
|
|
|
|
//
|
|
provider.Clean();
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
pPBar.Clean();
|
|
signalBox.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Conditions ...
|
|
bool DetectSignalTrigger(
|
|
//
|
|
X121SMCStrategyXICHSignalConditions &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(X121SMC_XICH_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;
|
|
}
|
|
|
|
//
|
|
// 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 ...
|
|
X121SMCStrategyXICHSignalConditions tmpItems[];
|
|
Copy(
|
|
mConditionsCollection,
|
|
tmpItems //
|
|
);
|
|
|
|
//
|
|
// Prese Item Data ...
|
|
bool isBullish = IsBullish(mConditions.dir);
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
X121SMCStrategyXICHSignalConditions 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;
|
|
|
|
/**
|
|
* Initialize ...
|
|
*/
|
|
void Init()
|
|
{
|
|
//
|
|
rfRewar = 2;
|
|
useGuards = false;
|
|
}
|
|
|
|
/**
|
|
* DeInitialize ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
mConditions.Clean();
|
|
Clean(mConditionsCollection);
|
|
|
|
//
|
|
mObjects.Clear();
|
|
mBarObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Update To Time of Exists Components ...
|
|
*
|
|
* @param value: updated time ...
|
|
*/
|
|
void UpdateTo(
|
|
datetime value = NULL //
|
|
)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |