This commit is contained in:
2025-01-15 22:09:21 +03:30
parent 341992374c
commit 9b307ae6e6
12 changed files with 3448 additions and 671 deletions
@@ -1365,6 +1365,52 @@ class XC121SMCExpert : public XCBaseExpert
}
}
/**
* Handle Strategies Guards ...
*/
void HandleStrategiesGuard() override
{
//
int count = ArraySize(mStrategies);
if (!IsValidSize(count))
{
return;
}
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(
positions, // Result ...
NULL, // Symbol ...
NULL, // Provider ...
NULL, // Period ...
X_POSITION_TYPE_ALL // All Types ...
);
if (!IsValidSize(positionsCount))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
// Call Tick Handler Function ...
X121SMCGuard iGuards[];
bool hasGuards = mStrategies[i].HandleGuard(
iGuards,
positions //
);
if (hasGuards)
{
HandleGuards(iGuards);
}
}
//
Clean(positions);
}
//
// Event Handlers ...
@@ -1819,6 +1865,393 @@ class XC121SMCExpert : public XCBaseExpert
return result;
}
/**
* Handle Guard Actions ...
*
* @param guards: X121SMCGuard instance Collection ...
*/
void HandleGuards(X121SMCGuard &guards[])
{
//
int count = ArraySize(guards);
if (!IsValidSize(guards))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
X121SMCGuard iGuard = guards[i];
//
if (!iGuard.IsValid())
{
continue;
}
//
// Here we Have to Handle Guard Actions ...
//
// Close ...
bool canClose =
NotEmpty(iGuard.ticket) &&
iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE;
//
// Close All ...
bool canCloseAll = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_ALL;
//
// Close Longs ...
bool canCloseLongs = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_LONGS;
//
// Close Shorts ...
bool canCloseShorts = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_SHORTS;
//
// Partial Close ...
bool canPartialClose =
NotEmpty(iGuard.ticket) &&
iGuard.volumeMultiplier > 0 &&
iGuard.action == X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE;
//
// Trail Stop ...
bool canTrailStop =
iGuard.sl > 0 &&
NotEmpty(iGuard.ticket) &&
iGuard.action == X_121_SMC_GUARD_ACTION_TRAIL_STOP;
//
// Trail Target ...
bool canTrailTarget =
iGuard.tp > 0 &&
NotEmpty(iGuard.ticket) &&
iGuard.action == X_121_SMC_GUARD_ACTION_TRAIL_TARGET;
//
// Hedge ...
bool canHedge = iGuard.action == X_121_SMC_GUARD_ACTION_HEDGE;
//
// Check is Guard Valid ...
bool isValidGuardAction =
canHedge ||
canClose ||
canCloseAll ||
canTrailStop ||
canCloseLongs ||
canTrailTarget ||
canCloseShorts ||
canPartialClose;
if (!isValidGuardAction)
{
continue;
}
//
// Now we Sure to Have a Valid Guard ...
// Start to o Guard Actions ...
//
// Close All ...
if (canCloseAll)
{
//
XPosition positions[];
int positionsCount =
mTrader
.GetPositions(
positions, // Result ...
iGuard.symbol,
iGuard.provider,
NULL, // Period ...
X_POSITION_TYPE_ALL, // All Types ...
true // Filter by Magic ...
);
if (IsValidSize(positionsCount))
{
//
string comment = "Guard Close All ...";
string message = "Guard Close All (" + ToString(positionsCount) + ") Positions Successfully ...";
mTradeHandler.ForceClose(
positions,
comment,
message //
);
}
}
//
// Close Longs ...
if (canCloseLongs)
{
//
XPosition longPositions[];
XPosition shortPositions[];
mTrader
.GetPositions(
longPositions, // Result ...
shortPositions, // Result ...
iGuard.symbol,
iGuard.provider,
NULL, // Period ...
true // Filter by Magic ...
);
//
int longPositionsCount = ArraySize(longPositions);
bool hasLongPositions = IsValidSize(longPositionsCount);
//
int shortPositionsCount = ArraySize(shortPositions);
bool hasShortPositions = IsValidSize(shortPositionsCount);
//
if (hasLongPositions)
{
//
string comment = "Guard Close Longs ...";
string message = "Guard Close (" + ToString(longPositionsCount) + ") Long Positions Successfully ...";
mTradeHandler.ForceClose(
longPositions,
comment,
message //
);
}
}
//
// Close Shorts ...
if (canCloseShorts)
{
//
XPosition longPositions[];
XPosition shortPositions[];
mTrader
.GetPositions(
longPositions, // Result ...
shortPositions, // Result ...
iGuard.symbol,
iGuard.provider,
NULL, // Period ...
true // Filter by Magic ...
);
//
int longPositionsCount = ArraySize(longPositions);
bool hasLongPositions = IsValidSize(longPositionsCount);
//
int shortPositionsCount = ArraySize(shortPositions);
bool hasShortPositions = IsValidSize(shortPositionsCount);
//
if (hasShortPositions)
{
//
string comment = "Guard Close Shorts ...";
string message = "Guard Close (" + ToString(shortPositionsCount) + ") Short Positions Successfully ...";
mTradeHandler.ForceClose(
shortPositions,
comment,
message //
);
}
}
//
// Close ...
if (canClose)
{
//
XPosition iPosition;
bool hasPosition = mTrader.GetPosition(
iGuard.ticket,
iPosition //
);
//
bool isLong = IsLong(iPosition.type);
//
if (hasPosition)
{
//
XPosition positions[];
AddRef(
iPosition,
positions //
);
//
string comment = "Guard Close ...";
string message = "Guard Close " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Successfully ...";
mTradeHandler.ForceClose(
positions,
comment,
message //
);
}
}
//
// Partial Close ...
if (canPartialClose)
{
//
// TODO: Implement this ..
}
//
// Hedge ...
if (canHedge)
{
//
XPosition positions[];
int positionsCount =
mTrader
.GetPositions(
positions, // Result ...
iGuard.symbol,
iGuard.provider,
NULL, // Period ...
X_POSITION_TYPE_ALL, // All Types ...
true // Filter by Magic ...
);
if (IsValidSize(positionsCount))
{
//
int longs = 0;
double longProfits = 0;
double longVolumes = 0;
//
int shorts = 0;
double shortProfits = 0;
double shortVolumes = 0;
CountPositions(
positions,
longs,
longProfits,
longVolumes,
shorts,
shortProfits,
shortVolumes //
);
//
int count = longs + shorts;
double profits = longProfits + shortProfits;
double volumes = longVolumes + shortVolumes;
//
bool canDoHedge =
count > 0 &&
profits > 0 &&
volumes > 0;
if (canDoHedge)
{
//
string comment = "Guard Hedge ...";
string message = "Guard Hedge (" + ToString(count) + ") Positions by: (" + ToString(profits) + ") Successfully ...";
mTradeHandler.ForceClose(
positions,
comment,
message //
);
}
}
}
//
// Trail Stop ...
if (canTrailStop)
{
//
XPosition iPosition;
bool hasPosition = mTrader.GetPosition(
iGuard.ticket,
iPosition //
);
//
bool isLong = IsLong(iPosition.type);
//
bool canDoTrail =
hasPosition &&
iPosition.profit > 0 &&
isLong
? iPosition.price > iGuard.sl &&
(iPosition.sl == 0 ||
iPosition.sl < iGuard.sl)
: iPosition.price < iGuard.sl &&
(iPosition.sl == 0 ||
iPosition.sl > iGuard.sl);
if (canDoTrail)
{
//
string comment = "Guard Trail Stop ...";
string message = "Guard Trail " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Stop Successfully ...";
bool isModified = mTrader.Modify(
iPosition.ticket,
iGuard.sl,
iPosition.tp,
comment //
);
if (isModified)
{
mTradeHandler.Alert(message);
}
}
}
//
// Trail Target ...
if (canTrailTarget)
{
//
XPosition iPosition;
bool hasPosition = mTrader.GetPosition(
iGuard.ticket,
iPosition //
);
//
bool isLong = IsLong(iPosition.type);
//
bool canDoTrail =
hasPosition &&
iGuard.tp != iPosition.tp &&
isLong
? iGuard.tp > iPosition.price
: iGuard.tp < iPosition.price;
if (canDoTrail)
{
//
string comment = "Guard Trail Target ...";
string message = "Guard Trail " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Target Successfully ...";
bool isModified = mTrader.Modify(
iPosition.ticket,
iPosition.sl,
iGuard.tp,
comment //
);
if (isModified)
{
mTradeHandler.Alert(message);
}
}
}
}
}
//
};