add Guard Event and Attached it to all Realted Classes till Final Handler in eaTradeManager ...

This commit is contained in:
2025-09-11 14:54:31 +03:30
parent 07d56d4f8b
commit 5eaeb13087
4 changed files with 452 additions and 246 deletions
+128 -1
View File
@@ -160,6 +160,12 @@ struct XGuard
} }
}; };
//
// an Event Type for Notify Guard Triggered ...
typedef void (*TOnGuarded)(
ENUM_X_GUARD_ACTIONS guard,
XPosition &positions[]);
// //
// Extensions ... // Extensions ...
@@ -226,6 +232,7 @@ class XCGuard : public XCBase
// Props ... // Props ...
double minVolumeFactorForHedge; // Minimum Volume Factor for Hedge Profit Calculation ... double minVolumeFactorForHedge; // Minimum Volume Factor for Hedge Profit Calculation ...
double minProfitPerVolumeFactorForHedge; // Minimum Required Profit per Volume Factor for Hedg ... double minProfitPerVolumeFactorForHedge; // Minimum Required Profit per Volume Factor for Hedg ...
TOnGuarded onGuardEventListener; // On Guard Event Listener ...
// //
// Constructor(s) ... // Constructor(s) ...
@@ -1005,6 +1012,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionGuard(guard.action, position);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1070,6 +1080,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1135,6 +1148,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1200,6 +1216,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1265,6 +1284,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1330,6 +1352,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1395,6 +1420,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1426,7 +1454,50 @@ class XCGuard : public XCBase
} }
// //
// Do What we want ... // Retrieve Positions ...
XPosition positions[];
int count = GetShortPositions(
positions,
guard //
);
has = IsValidSize(count);
if (!has)
{
//
Clean(positions);
//
return;
}
//
string comment = "Guard Close Shorts ...";
//
has = trader.Close(
positions,
comment //
);
if (has)
{
//
HandleNotifyPositionsGuard(guard.action, positions);
//
string message =
"Guard Closed " +
ToXString(count) +
" Long Positions Successfully ...";
//
alert.SendAlert(message);
}
//
// Cleanup Resources ...
//
Clean(positions);
} }
// //
@@ -1477,6 +1548,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1542,6 +1616,10 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
//
// //
string message = string message =
"Guard Closed " + "Guard Closed " +
@@ -1633,6 +1711,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionGuard(guard.action, position);
// //
string message = string message =
"Guard Closed Partially " + "Guard Closed Partially " +
@@ -1736,6 +1817,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionGuard(guard.action, position);
// //
double before = NormalizePrice(position.sl, position.symbol); double before = NormalizePrice(position.sl, position.symbol);
double after = NormalizePrice(guard.sl, position.symbol); double after = NormalizePrice(guard.sl, position.symbol);
@@ -1841,6 +1925,9 @@ class XCGuard : public XCBase
); );
if (has) if (has)
{ {
//
HandleNotifyPositionGuard(guard.action, position);
// //
double before = NormalizePrice(position.tp, position.symbol); double before = NormalizePrice(position.tp, position.symbol);
double after = NormalizePrice(guard.tp, position.symbol); double after = NormalizePrice(guard.tp, position.symbol);
@@ -1981,6 +2068,9 @@ class XCGuard : public XCBase
has = IsValidSize(closedCount); has = IsValidSize(closedCount);
if (has) if (has)
{ {
//
HandleNotifyPositionsGuard(guard.action, positions);
// //
string message = string message =
"Guard Hedge " + "Guard Hedge " +
@@ -2007,6 +2097,43 @@ class XCGuard : public XCBase
XCTrade *trader; XCTrade *trader;
XCAlert *alert; XCAlert *alert;
//
void HandleNotifyPositionGuard(
ENUM_X_GUARD_ACTIONS action,
XPosition &position //
)
{
//
if (!IsSpecifiedValid(action) || !position.IsValid() || onGuardEventListener == NULL)
{
return;
}
//
XPosition positions[];
AddRef(
position,
positions //
);
HandleNotifyPositionsGuard(action, positions);
}
//
void HandleNotifyPositionsGuard(
ENUM_X_GUARD_ACTIONS action,
XPosition &positions[] //
)
{
//
if (!IsSpecifiedValid(action) || !HasChild(positions) || onGuardEventListener == NULL)
{
return;
}
//
onGuardEventListener(action, positions);
}
// //
}; };
+288 -243
View File
@@ -510,6 +510,16 @@ class XCTradeManager : public XCBase
return; return;
} }
//
XGuard guards[];
int guardsCount = CheckForGuard(guards);
bool hasGuard = IsValidSize(guardsCount);
if (hasGuard)
{
//
guard.DoGuards(guards);
}
// //
double swapSum = 0; double swapSum = 0;
double profitSum = 0; double profitSum = 0;
@@ -1022,39 +1032,6 @@ class XCTradeManager : public XCBase
return result; return result;
} }
/**
* Handle All Exists Symbol Configurations Restrictions ...
*/
void HandleRestrictions()
{
//
// Count Symbol Configurations ...
int count = ArraySize(symbolTradeConfigs);
bool has = IsValidSize(count);
if (!has)
{
return;
}
//
// Handle Restrictions ...
datetime cTime = TimeCurrent();
bool isNewDay = timeTracker.IsNewDay();
for (int i = 0; i < count; i++)
{
//
// Reset Force Close At Time ...
if (isNewDay)
{
symbolTradeConfigs[i].isForceCloseAtTime = false;
}
//
// Handle Restrictions ...
symbolTradeConfigs[i].HandleRestrictions(cTime);
}
}
/** /**
* Handle Signal Recieved ... * Handle Signal Recieved ...
* *
@@ -1440,220 +1417,16 @@ class XCTradeManager : public XCBase
} }
/** /**
* Handle Force Close Trades ... * Handle Guard Events ...
*
* @param action: ENUM_X_GUARD_ACTIONS
* @param positions: XPosition[]
*/ */
bool HandleForceCloseTrades( void HandleGuardEvent(
ENUM_X_GUARD_ACTIONS action,
XPosition &positions[] // XPosition &positions[] //
) )
{ {
//
bool result = false;
//
result = HasChild(positions);
if (!result)
{
return result;
}
//
string prefix = "Protector: ";
string comment = "Force Close ...";
//
int count = ArraySize(positions);
for (int i = 0; i < count; i++)
{
HandleForceClose(positions[i]);
}
//
result = IsValidSize(count);
if (result)
{
//
string message = prefix + "Force Close (" + ToXString(count) + ") Trades at Specified Time ...";
HandleReportProtector(message);
}
//
return result;
}
//
// TODO: Complete this ...
void HandleGuard()
{
}
/**
* Apply Signal Volume ...
*
* @param signal: XSignal
*/
void HandleSignalVolume(XSignal &signal)
{
//
// Validate ...
if (!signal.IsValid())
{
return;
}
//
// Handle Volume Management ...
double iVolume = volume.CalculateVolume(signal);
bool has = iVolume > X_MIN_VOLUME &&
iVolume != signal.volume;
if (has)
{
signal.volume = iVolume;
}
}
/**
* Find Executed Trade by Providing Position Ticket ...
*
* @param index: int reference, holding founded item index ...
* @param ticket: ulong, Specified Position Ticket ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
ulong ticket //
)
{
//
bool result = false;
//
index = -1;
//
result =
ticket > 0 &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XTradeInfo iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.IsExecuted() &&
iTrade.positionID == ticket;
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Trade Item By Signal ...
*
* @param index: int reference, holding founded item index ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
XSignal &signal //
)
{
//
bool result = false;
//
index = -1;
//
result =
signal.IsValid() &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XTradeInfo iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.signal.IsSameAs(signal);
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Remove a Trade From List ...
*
* @param index: int ...
*/
void RemoveTrade(int index)
{
//
bool has =
HasChild(trades) &&
IsValidIndex(index) &&
index < ArraySize(trades);
if (!has)
{
return;
}
//
ArrayRemove(
trades,
index,
1 //
);
} }
// //
@@ -1787,6 +1560,133 @@ class XCTradeManager : public XCBase
alert.SendAlert(message); alert.SendAlert(message);
} }
/**
* Handle All Exists Symbol Configurations Restrictions ...
*/
void HandleRestrictions()
{
//
// Count Symbol Configurations ...
int count = ArraySize(symbolTradeConfigs);
bool has = IsValidSize(count);
if (!has)
{
return;
}
//
// Handle Restrictions ...
datetime cTime = TimeCurrent();
bool isNewDay = timeTracker.IsNewDay();
for (int i = 0; i < count; i++)
{
//
// Reset Force Close At Time ...
if (isNewDay)
{
symbolTradeConfigs[i].isForceCloseAtTime = false;
}
//
// Handle Restrictions ...
symbolTradeConfigs[i].HandleRestrictions(cTime);
}
}
/**
* Apply Signal Volume ...
*
* @param signal: XSignal
*/
void HandleSignalVolume(XSignal &signal)
{
//
// Validate ...
if (!signal.IsValid())
{
return;
}
//
// Handle Volume Management ...
double iVolume = volume.CalculateVolume(signal);
bool has = iVolume > X_MIN_VOLUME &&
iVolume != signal.volume;
if (has)
{
signal.volume = iVolume;
}
//
// Here we Can Implement Custom Signalling Volume Management
// based on Different Symbol Configurations ...
}
/**
* Handle Force Close Trades ...
*/
bool HandleForceCloseTrades(
XPosition &positions[] //
)
{
//
bool result = false;
//
result = HasChild(positions);
if (!result)
{
return result;
}
//
string prefix = "Protector: ";
string comment = "Force Close ...";
//
int count = ArraySize(positions);
for (int i = 0; i < count; i++)
{
HandleForceClose(positions[i]);
}
//
result = IsValidSize(count);
if (result)
{
//
string message = prefix + "Force Close (" + ToXString(count) + ") Trades at Specified Time ...";
HandleReportProtector(message);
}
//
return result;
}
/**
* Check For Guards ...
*
* @param dest: XGuard[]
*/
int CheckForGuard(XGuard &dest[])
{
//
int result = 0;
//
// Cleanup Dest ...
SpecifiedClean(dest);
//
// Check For Guards ...
//
result = ArraySize(dest);
//
return result;
}
// //
// Save Trades ... // Save Trades ...
bool SaveTrade( bool SaveTrade(
@@ -1995,6 +1895,151 @@ class XCTradeManager : public XCBase
XTradeInfo trades[]; XTradeInfo trades[];
XSymbolTradeConfig symbolTradeConfigs[]; XSymbolTradeConfig symbolTradeConfigs[];
/**
* Find Executed Trade by Providing Position Ticket ...
*
* @param index: int reference, holding founded item index ...
* @param ticket: ulong, Specified Position Ticket ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
ulong ticket //
)
{
//
bool result = false;
//
index = -1;
//
result =
ticket > 0 &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XTradeInfo iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.IsExecuted() &&
iTrade.positionID == ticket;
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Trade Item By Signal ...
*
* @param index: int reference, holding founded item index ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
XSignal &signal //
)
{
//
bool result = false;
//
index = -1;
//
result =
signal.IsValid() &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XTradeInfo iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.signal.IsSameAs(signal);
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Remove a Trade From List ...
*
* @param index: int ...
*/
void RemoveTrade(int index)
{
//
bool has =
HasChild(trades) &&
IsValidIndex(index) &&
index < ArraySize(trades);
if (!has)
{
return;
}
//
ArrayRemove(
trades,
index,
1 //
);
}
// //
void AddOrUpdateSymbolConfiguration(XSymbolTradeConfig &config) void AddOrUpdateSymbolConfiguration(XSymbolTradeConfig &config)
{ {
+17 -2
View File
@@ -207,6 +207,7 @@ int OnInit()
// //
// Attach Event Handlers ... // Attach Event Handlers ...
eaExpert.AddOnSignalEventHandler(OnSignalTriggered); eaExpert.AddOnSignalEventHandler(OnSignalTriggered);
eaExpert.onGuardedEventHandler = OnGuardedTriggered;
eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged);
eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered);
eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged);
@@ -296,11 +297,11 @@ void OnChartEvent(
/** /**
* Handle CanAnalyse Event Triggered ... * Handle CanAnalyse Event Triggered ...
* *
* @param symbol: Symbol ... * @param symbol: Symbol ...
* @param period: Period ... * @param period: Period ...
* @param time: Analysing Time ... * @param time: Analysing Time ...
* *
* @return ( bool ) * @return ( bool )
*/ */
bool CanAnalyseEventTriggered( bool CanAnalyseEventTriggered(
@@ -316,6 +317,20 @@ bool CanAnalyseEventTriggered(
); );
} }
/**
* Handle Guard Events ...
*
* @param action: ENUM_X_GUARD_ACTIONS
* @param positions: XPosition[]
*/
void OnGuardedTriggered(
ENUM_X_GUARD_ACTIONS action,
XPosition &positions[] //
)
{
eaExpert.OnGuardedTriggered(action, positions);
}
/** /**
* Trigger OnSignal Event ... * Trigger OnSignal Event ...
* *
+19
View File
@@ -114,6 +114,7 @@ class XCXOM1EAExpert : public XCBase
// Tools / Actions / Handlers ... // Tools / Actions / Handlers ...
// //
TOnGuarded onGuardedEventHandler;
TCanAnalyse canAnalyseEventHandler; TCanAnalyse canAnalyseEventHandler;
// //
@@ -502,6 +503,10 @@ class XCXOM1EAExpert : public XCBase
eaTrade // eaTrade //
); );
//
// Attach Event Handler ...
eaGuard.onGuardEventListener = onGuardedEventHandler;
// //
// Initialize Trae Manager ... // Initialize Trae Manager ...
eaTradeManager = new XCTradeManager( eaTradeManager = new XCTradeManager(
@@ -737,6 +742,20 @@ class XCXOM1EAExpert : public XCBase
eaTradeManager.HandleSignal(signal); eaTradeManager.HandleSignal(signal);
} }
/**
* Handle Guard Events ...
*
* @param action: ENUM_X_GUARD_ACTIONS
* @param positions: XPosition[]
*/
void OnGuardedTriggered(
ENUM_X_GUARD_ACTIONS action,
XPosition &positions[] //
)
{
eaTradeManager.HandleGuardEvent(action, positions);
}
// //
// Check Can Analyse ... // Check Can Analyse ...
bool HandleCanAnalyseEventTriggered( bool HandleCanAnalyseEventTriggered(