- Create a Data Collector Class;

- Add Support for Save Logs in Alert Class;
- Add Propper inputs for Handle Saving Logs in EA and Expert Class;
- remove x-trade.manager Class Data Collector and use General Developed Data Collector;
- Add Support for Reading Fles in Data Collector Class for Support Configuration Parsing;
- Remove XCBaseAlert class and add Support for get XCAlert instance reference pointer as Dependency Injection in all used classed and Refactor all Changes;
- Apply Fix some UnImplemented Event Handlers on Ea Expert Class of XCATBEA and also change Event Handler Binding to Collection Based Model;
- Test all Functionalities ...
- Apply Some Fixes on Prevent Double Saing Same Log Messages ...
This commit is contained in:
2025-06-05 05:35:47 +03:30
parent 4e941f3a65
commit e46cac2ab1
12 changed files with 2107 additions and 927 deletions
+324 -58
View File
@@ -107,12 +107,12 @@ class XCXCATBEAExpert : public XCBase
bool eaAllowSignallingBasedOnTriggerBlocksInsideOther; // Signalling Based on Trigger Blocks Seccond inputs
bool eaSecondsTriggersSLUsingFirstTriggerBlock; // Use First Trigger Block for SL of Seconds Trigger Block Signalss
bool eaApplyValidateAndFilterOnSelectInsideOthers; // Select Trigger Blocks by Applying Validations and Filterss
bool eaAllowSignallingConditions1; // Allow Market Conditions Signaller to Using Sar Starter Signals
bool eaAllowSignallingConditions2; // Allow Market Conditions Signaller to Using Trend Starter Signals
bool eaAllowSignallingConditions3; // Allow Market Conditions Signaller to Using Delta Starter Signals
bool eaAllowSignallingConditions4; // Allow Market Conditions Signaller to Using Volume Starter Signals
bool eaAllowSignallingConditions5; // Allow Market Conditions Signaller to Using Signal Bar Starter Signals
bool eaAllowSignallingConditions6; // Allow Market Conditions Signaller to Using HK Signal Bar Starter Signals
bool eaAllowSignallingConditions1; // Allow Market Conditions Signaller to Using Sar Starter Signals
bool eaAllowSignallingConditions2; // Allow Market Conditions Signaller to Using Trend Starter Signals
bool eaAllowSignallingConditions3; // Allow Market Conditions Signaller to Using Delta Starter Signals
bool eaAllowSignallingConditions4; // Allow Market Conditions Signaller to Using Volume Starter Signals
bool eaAllowSignallingConditions5; // Allow Market Conditions Signaller to Using Signal Bar Starter Signals
bool eaAllowSignallingConditions6; // Allow Market Conditions Signaller to Using HK Signal Bar Starter Signals
//
// Volume ...
@@ -144,6 +144,7 @@ class XCXCATBEAExpert : public XCBase
//
// Alert ...
bool eaEnableAlerts; // Enable Alerts
bool eaSaveAlerts; // Save Alerts
bool eaLogAlerts; // Log Alerts
bool eaMailAlerts; // Mail Alerts
bool eaPushAlerts; // Push Alerts
@@ -169,18 +170,6 @@ class XCXCATBEAExpert : public XCBase
bool eaSaveLosts; // Save Lost Conditions
bool eaSaveRestrictions; // Save Restriction Reports
//
// Trade Event Handlers ...
TOnModify OnModifyEventHandler;
TOnStopLoss OnStopLossEventHandler;
TOnForceClose OnForceCloseEventHandler;
TOnTakeProfit OnTakeProfitEventHandler;
TOnPartialClose OnPartialCloseEventHandler;
TOnDealsChanged OnDealsChangedEventHandler;
TOnOrdersChanged OnOrdersChangedEventHandler;
TOnPositionsChanged OnPositionsChangedEventHandler;
TOnTradeStateChanged OnTradeStateChangedEventHandler;
//
// Requirements ...
@@ -196,6 +185,162 @@ class XCXCATBEAExpert : public XCBase
//
// Tools / Actions / Handlers ...
//
// Trade Event Handlers ...
//
void AddOnStopLossEventHandler(TOnStopLoss handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mStopLossEventHandlers
//
);
}
//
void AddOnTakeProfitEventHandler(TOnTakeProfit handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mTakeProfitEventHandlers
//
);
}
//
void AddOnDealsChangedEventHandler(TOnDealsChanged handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mDealsChangedEventHandlers
//
);
}
//
void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mOrdersChangedEventHandlers
//
);
}
//
void AddOnModifyPositionEventHandler(TOnModify handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mOnModifyEventHandlers
//
);
}
//
void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mPositionsChangedEventHandlers
//
);
}
//
void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mTradeStateChangedEventHandlers
//
);
}
//
void AddOnForceClosePositionEventHandler(TOnForceClose handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mOnForceCloseEventHandlers
//
);
}
//
void AddOnPartialClosePositionEventHandler(TOnPartialClose handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mOnPartialCloseEventHandlers
//
);
}
//
// Validators ...
@@ -239,6 +384,10 @@ class XCXCATBEAExpert : public XCBase
return result;
}
//
bool has = false;
int count = -1;
//
// Initialize Alert Handler ...
eaAlert = new XCAlert();
@@ -246,6 +395,7 @@ class XCXCATBEAExpert : public XCBase
eaAlert.SetLogAlerts(eaLogAlerts);
eaAlert.SetMailAlerts(eaMailAlerts);
eaAlert.SetPushAlerts(eaPushAlerts);
eaAlert.SetSaveAlerts(eaSaveAlerts);
eaAlert.SetEnableAlerts(eaEnableAlerts);
eaAlert.SetTerminalAlerts(eaTerminalAlerts);
@@ -275,44 +425,139 @@ class XCXCATBEAExpert : public XCBase
eaMaxAllowedPositions,
eaMaxAllowedDrawdownFactor //
);
eaTrade.AddOnStopLossEventHandler(OnStopLossEventHandler);
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitEventHandler);
eaTrade.AddOnModifyPositionEventHandler(OnModifyEventHandler);
eaTrade.AddOnDealsChangedEventHandler(OnDealsChangedEventHandler);
eaTrade.AddOnOrdersChangedEventHandler(OnOrdersChangedEventHandler);
eaTrade.AddOnForceClosePositionEventHandler(OnForceCloseEventHandler);
eaTrade.AddOnPartialClosePositionEventHandler(OnPartialCloseEventHandler);
eaTrade.AddOnPositionsChangedEventHandler(OnPositionsChangedEventHandler);
eaTrade.AddOnTradeStateChangedEventHandler(OnTradeStateChangedEventHandler);
//
// Trade Handler Attachments ...
//
// Position Modifiy Event Handlers ...
count = ArraySize(mOnModifyEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]);
}
}
//
// Position Stop Loss Event Handlers ...
if (has)
{
//
count = ArraySize(mStopLossEventHandlers);
has = IsValidSize(count);
for (int i = 0; i < count; i++)
{
eaTrade.AddOnStopLossEventHandler(mStopLossEventHandlers[i]);
}
}
//
// Position Take Profit Event Handlers ...
count = ArraySize(mTakeProfitEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]);
}
}
//
// Position Force Close Event Handlers ...
count = ArraySize(mOnForceCloseEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]);
}
}
//
// Deals Changed Event Handlers ...
count = ArraySize(mDealsChangedEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]);
}
}
//
// Orders Changed Event Handlers ...
count = ArraySize(mOrdersChangedEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]);
}
}
//
// Positions Changed Event Handlers ...
count = ArraySize(mPositionsChangedEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]);
}
}
//
// Trade Changed Event Handlers ...
count = ArraySize(mTradeStateChangedEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]);
}
}
//
// Postion Partially Close Event Handlers ...
count = ArraySize(mOnPartialCloseEventHandlers);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
eaTrade.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]);
}
}
//
// Initialize Guard Handler ...
eaGuard = new XCGuard(
eaAlert,
eaTrade //
);
//
eaGuard.SetAlertPrefix(eaLogSuffix);
eaGuard.SetAlertLogAlerts(eaLogAlerts);
eaGuard.SetAlertMailAlerts(eaMailAlerts);
eaGuard.SetAlertPushAlerts(eaPushAlerts);
eaGuard.SetAlertEnableAlerts(eaEnableAlerts);
eaGuard.SetAlertTerminalAlerts(eaTerminalAlerts);
//
// Initialize Trae Manager ...
eaTradeManager = new XCXCATBEATradeManager(
eaAlert,
eaTrade //
);
//
eaTradeManager.SetAlertPrefix(eaLogSuffix);
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
//
eaTradeManager.SaveWins(eaSaveWins);
eaTradeManager.SaveLosts(eaSaveLosts);
@@ -804,6 +1049,7 @@ class XCXCATBEAExpert : public XCBase
*/
void HandleOnTrade()
{
eaTrade.HandleOnTrade();
}
/**
@@ -840,6 +1086,7 @@ class XCXCATBEAExpert : public XCBase
*/
void HandleOnStopLossTriggered(const XDeal &deal)
{
eaTradeManager.HandleSL(deal);
}
/**
@@ -849,6 +1096,7 @@ class XCXCATBEAExpert : public XCBase
*/
void HandleOnTakeProfitTriggered(const XDeal &deal)
{
eaTradeManager.HandleTP(deal);
}
/**
@@ -864,21 +1112,7 @@ class XCXCATBEAExpert : public XCBase
const string comment //
)
{
}
/**
* Handle Position Modified Event ...
*
* @param ticket: ulong, triggered Positions ticket ...
* @param profit: double, Position Profit ...
* @param comment: string, Comment ...
*/
void HandleOnPositionModified(
const ulong ticket,
const double profit,
const string comment //
)
{
eaTradeManager.HandleForceClose(position);
}
/**
@@ -894,6 +1128,12 @@ class XCXCATBEAExpert : public XCBase
const string comment //
)
{
//
eaTradeManager.HandlePartiallyClosed(
ticket,
profit,
comment //
);
}
/**
@@ -929,6 +1169,21 @@ class XCXCATBEAExpert : public XCBase
{
}
/**
* Handle Position Modified Event ...
*
* @param ticket: ulong, triggered Positions ticket ...
* @param profit: double, Position Profit ...
* @param comment: string, Comment ...
*/
void HandleOnPositionModified(
const ulong ticket,
const double profit,
const string comment //
)
{
}
/**
* Handle all Trades States Changed Event ...
*
@@ -1149,6 +1404,17 @@ class XCXCATBEAExpert : public XCBase
private:
//
//
TOnModify mOnModifyEventHandlers[];
TOnStopLoss mStopLossEventHandlers[];
TOnTakeProfit mTakeProfitEventHandlers[];
TOnForceClose mOnForceCloseEventHandlers[];
TOnDealsChanged mDealsChangedEventHandlers[];
TOnOrdersChanged mOrdersChangedEventHandlers[];
TOnPartialClose mOnPartialCloseEventHandlers[];
TOnPositionsChanged mPositionsChangedEventHandlers[];
TOnTradeStateChanged mTradeStateChangedEventHandlers[];
//
};
@@ -1,209 +0,0 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCXCATBEADataCollector ...
// Description: Class for XCATBEA Data Collector ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Class for XCATBEA Data Collector"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
//
// Definitions ...
//
// Implementation ...
class XCXCATBEADataCollector : public XCBase
{
//
// Public ...
public:
//
// Constructors ...
XCXCATBEADataCollector()
{
}
//
// Deconstructor ...
~XCXCATBEADataCollector()
{
}
//
// Properties ...
//
string Path()
{
return mPath;
}
//
void Path(string value)
{
//
// Normalizing Collector Path ...
if (IsValid(value))
{
mPath = value;
}
else
{
mPath = "XCXCATBEADataCollector";
}
}
//
// Tools ...
//
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
mPath + "\\" + fileName + ".x121.log"
//
;
//
return result;
}
//
int GetFileHandlerForWrite(string filePath)
{
//
int result = INVALID_HANDLE;
//
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_WRITE | FILE_TXT //
);
//
return result;
}
/**
* Save Specified Content into Specified File Name ...
*
* @param fileName: string, file name ...
* @param content: string, content ...
*
* @return ( bool )
*/
bool Save(
string fileName,
string content //
)
{
//
bool result = false;
//
result = IsValid(content);
if (!result)
{
return result;
}
//
//
int mHandler = GetFileHandlerForWrite(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
/**
* Append Specified Content into Specified File Name ...
*
* @param fileName: string, file name ...
* @param content: string, content ...
*
* @return ( bool )
*/
bool Append(
string fileName,
string content //
)
{
//
bool result = false;
//
result = IsValid(content);
if (!result)
{
return result;
}
//
//
int mHandler = GetFileHandlerForWrite(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileSeek(mHandler, 0, SEEK_END);
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
//
string mPath; // Base Collector Path ...
};
@@ -22,10 +22,10 @@
//
// Imports ...
#include "../../Classes/x-saherelm.x-alert.class.mq5"
#include "../../Classes/x-saherelm.x-data.collector.class.mq5"
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../../Classes/x-saherelm.x-trade.class.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../Classes/xcatbea.x-data.collector.class.mq5"
#include "../Libraries/xcatbea.lib.mq5"
#include "../Libraries/xcatbea.signaller.lib.mq5"
@@ -1594,27 +1594,29 @@ struct XCATBEATrade
//
// Implementations ...
class XCXCATBEATradeManager : public XCBaseAlert
class XCXCATBEATradeManager : public XCBase
{
//
// Public ...
public:
//
// Props ...
XCAlert *alert;
XCTrade *trader;
bool drawSignal;
XCPOIDrawer *drawer;
XTimeTracker timeTracker;
XCXCATBEADataCollector *collector;
XCDataCollector *collector;
//
// Constructors ...
XCXCATBEATradeManager(
XCTrade *&_trader,
string _path = NULL // Base Path
XCAlert *_alert,
XCTrade *_trader //
)
{
//
alert = _alert;
trader = _trader;
drawSignal = true;
drawer = new XCPOIDrawer();
@@ -1644,15 +1646,12 @@ class XCXCATBEATradeManager : public XCBaseAlert
SaveTrades(false);
//
// Normalizing Collector Path ...
if (!IsValid(_path))
{
_path = "X121XCATBEATradeManager" + "\\" + trader.mAccount.GetCompany();
}
collector = new XCDataCollector();
//
collector = new XCXCATBEADataCollector();
collector.Path(_path);
// Setting Collector Path ...
string mPath = alert.GetPrefix() + "\\" + trader.mAccount.GetCompany();
collector.Path(mPath);
}
//
@@ -1666,8 +1665,15 @@ class XCXCATBEATradeManager : public XCBaseAlert
timeTracker.Clean();
//
ZeroMemory(alert);
ZeroMemory(trader);
//
delete drawer;
ZeroMemory(drawer);
//
delete collector;
ZeroMemory(collector);
}
@@ -2283,7 +2289,7 @@ class XCXCATBEATradeManager : public XCBaseAlert
{
//
string message = signal.GetMessage("Provided");
SendAlert(message);
alert.SendAlert(message);
}
//
@@ -2474,7 +2480,7 @@ class XCXCATBEATradeManager : public XCBaseAlert
}
//
SendAlert(message);
alert.SendAlert(message);
}
//
@@ -3183,10 +3189,10 @@ class XCXCATBEATradeManager : public XCBaseAlert
//
string message =
(IsValid(prefix)
? prefix + "\n"
? prefix + " | "
: "") +
"Account Balance: " + ToString(balance) + currency;
SendAlert(message);
alert.SendAlert(message);
}
//
@@ -3199,7 +3205,7 @@ class XCXCATBEATradeManager : public XCBaseAlert
}
//
SendAlert(message);
alert.SendAlert(message);
}
//
@@ -3595,7 +3601,7 @@ class XCXCATBEATradeManager : public XCBaseAlert
{
//
string message = iInfo.GetRestrictionDescription(restrictionsPeriod);
SendAlert(message);
alert.SendAlert(message);
}
SaveRestrictions(iInfo);