start implementing XTrade Handler Class ...

This commit is contained in:
2024-07-22 02:04:16 +03:30
parent d194d85082
commit d1e8daa131
5 changed files with 853 additions and 38 deletions
+66
View File
@@ -52,6 +52,7 @@ public:
double _r2r, // Risk/Reward Ratio double _r2r, // Risk/Reward Ratio
int _slippage, // Trader Slippage int _slippage, // Trader Slippage
long _magicNumber, // Trader Magic Number long _magicNumber, // Trader Magic Number
bool _ignoreSignalExecution = false, // Ignore Signal Execution
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
double _tpPoint = 0, // TP As Point double _tpPoint = 0, // TP As Point
@@ -82,6 +83,7 @@ public:
mMaxAllowedLongs = _maxAllowedLongs; mMaxAllowedLongs = _maxAllowedLongs;
mMaxAllowedShorts = _maxAllowedShorts; mMaxAllowedShorts = _maxAllowedShorts;
mForceMaxTPSLAsPoint = _forceMaxTPSLAsPoint; mForceMaxTPSLAsPoint = _forceMaxTPSLAsPoint;
mIgnoreSignalExecution = _ignoreSignalExecution;
// //
mForceDisabled = false; mForceDisabled = false;
@@ -371,6 +373,29 @@ public:
mIgnoreSL = value; mIgnoreSL = value;
} }
//
bool IgnoreSignalExecution()
{
return mIgnoreSignalExecution;
}
//
void IgnoreSignalExecution(bool value)
{
mIgnoreSignalExecution = value;
}
//
// On Signal Handlers ...
void AddSignalEventHandler(TOnSignal handler)
{
//
Add(
handler,
mOnSignalEventHandlers //
);
}
// //
// Virtual Methods ... // Virtual Methods ...
@@ -600,6 +625,18 @@ public:
signal.sl = 0; signal.sl = 0;
} }
//
// Notify Signal Event Handler(s) ...
NotifyOnSignalEventHandlers(signal);
//
// Check Signal Execution Enabled or not ...
result = !mIgnoreSignalExecution;
if (!result)
{
return result;
}
// //
ENUM_X_SIGNAL_EXECUTION_RESULT state; ENUM_X_SIGNAL_EXECUTION_RESULT state;
result = trader.ExecuteSignal( result = trader.ExecuteSignal(
@@ -658,6 +695,7 @@ protected:
double mSLPoint; // SL As Point double mSLPoint; // SL As Point
bool mIgnoreTP; // TP set to 0 bool mIgnoreTP; // TP set to 0
bool mIgnoreSL; // SL set to 0 bool mIgnoreSL; // SL set to 0
bool mIgnoreSignalExecution; // Ignore Signal Execution
// //
string mSymbol; // Trading Symbol ... string mSymbol; // Trading Symbol ...
@@ -687,11 +725,39 @@ protected:
barTracker.Clean(); barTracker.Clean();
} }
//
// Notified Signal Event Handler(s) ...
void NotifyOnSignalEventHandlers(XSignal &signal)
{
//
if (!signal.IsValid())
{
return;
}
//
int count = ArraySize(mOnSignalEventHandlers);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
mOnSignalEventHandlers[i](signal);
}
}
// //
// Private ... // Private ...
private: private:
// //
// Props ... // Props ...
//
// On Signal Recieved Event Handler(s) ...
TOnSignal mOnSignalEventHandlers[];
}; };
// //
+311
View File
@@ -22,6 +22,7 @@
// //
// Imports ... // Imports ...
#include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.base.class.mq5"
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Libraries/x-saherelm.xtrade.lib.mq5" #include "../Libraries/x-saherelm.xtrade.lib.mq5"
#include "../Classes/x-saherelm.xaccount.class.mq5" #include "../Classes/x-saherelm.xaccount.class.mq5"
@@ -3773,3 +3774,313 @@ private:
}; };
// //
// Trade Handler Class ...
class XSCXTradeHandler : public XSCBaseAlert
{
//
// Public ...
public:
//
//
// Constructor(s) ...
void XSCXTradeHandler(XSCTrade *trader)
{
//
mTrader = trader;
}
//
// Deconstructor ...
void ~XSCXTradeHandler()
{
//
delete mTrader;
}
//
// First Step of Trade Handling ...
// Since Must Call when a Signal Executed ...
void AddExecutedSignal(
XSignal &signal, // Executed Signal
double commission = 0 // Commission
)
{
//
// Check Signal Valid ...
if (!signal.IsValid())
{
return;
}
//
XTradeData item;
bool isFilled = item.Fill(signal);
if (!isFilled)
{
return;
}
//
item.commission = commission;
//
Add(item);
}
//
// this Method call's by a Timer,
// or in OnTick for Update Positions,
// Data ...
void UpdateData()
{
//
XPosition positions[];
int count = mTrader.GetPositions(positions);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
XPosition iPosition = positions[i];
//
int idx = -1;
bool isExists = HasItem(
iPosition.ticket,
idx //
);
if (!isExists)
{
//
// Add New Data ...
//
// Find Executed Signal Deal History ...
XDeal deals[];
double commission = 0;
int dealsCount = mTrader.GetDeals(
deals,
iPosition.symbol,
iPosition.provider,
iPosition.period,
NULL,
DEAL_ENTRY_IN //
);
if (IsValidSize(dealsCount))
{
//
for (int i = 0; i < dealsCount; i++)
{
//
XDeal iDeal = deals[i];
if (iDeal.positionId == iPosition.ticket)
{
//
commission = iDeal.commission;
break;
}
}
}
//
XTradeData iData;
iData.Fill(
iPosition //
);
//
iData.ticket = iPosition.ticket;
//
Add(iData);
}
else
{
//
// Update Exists ...
mData[idx].Update(iPosition);
}
}
}
//
// Protected ...
protected:
//
XSCTrade *mTrader; // Instance of Trader Class
//
XTradeData mData[]; // Hold Trade Data
//
// Private ...
private:
//
// Props ...
//
// Count Data ...
int Count()
{
return ArraySize(mData);
}
//
// Add Item ...
bool Add(XTradeData &item)
{
//
bool result = false;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
int index = -1;
if (item.ticket > 0)
{
//
result = !HasItem(
item.ticket,
index //
);
}
else
{
//
result = !HasItem(
item.symbol,
item.provider,
item.period,
item.type,
index //
);
}
if (!result || IsValidIndex(index))
{
//
result = false;
return result;
}
//
AddRef(
item,
mData //
);
//
return result;
}
//
// Find Item Index ...
bool HasItem(
ulong ticket,
int &index //
)
{
//
bool result = false;
//
index = -1;
//
int count = Count();
result = IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
result = mData[i].IsOwn(ticket);
if (result)
{
//
index = i;
break;
}
}
//
return result;
}
//
// Find Item Index ...
bool HasItem(
string symbol,
string provider,
ENUM_TIMEFRAMES period,
ENUM_X_POSITION_TYPES type,
int &index //
)
{
//
bool result = false;
//
index = -1;
//
// Validate ...
result =
//
IsValid(symbol) &&
IsValid(period) &&
IsValid(provider) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
if (!result)
{
return result;
}
//
int count = Count();
result = IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
result = mData[i].IsOwn(
symbol,
provider,
period,
type //
);
if (result)
{
//
index = i;
break;
}
}
//
return result;
}
};
//
+86 -8
View File
@@ -67,6 +67,14 @@ XSCXCCHelper *mCCHelper;
// Registred Strategies ... // Registred Strategies ...
XSCBaseStrategy *strategies[]; XSCBaseStrategy *strategies[];
//
// Trader Instance Class ...
XSCTrade *eaTrader;
//
// Trade Handler Instance Class ...
XSCXTradeHandler *eaTradeHandler;
// //
// Event Handlers ... // Event Handlers ...
@@ -90,7 +98,7 @@ int OnInit()
drawPrefix = ShortName; drawPrefix = ShortName;
// //
// EventSetTimer(1); EventSetTimer(5);
// EventSetMillisecondTimer(100); // EventSetMillisecondTimer(100);
// //
@@ -120,7 +128,11 @@ void OnDeinit(const int reason)
delete mCCHelper; delete mCCHelper;
// //
// EventKillTimer(); delete eaTrader;
delete eaTradeHandler;
//
EventKillTimer();
// //
Clean(strategies); Clean(strategies);
@@ -130,19 +142,14 @@ void OnDeinit(const int reason)
// On Tick Handler ... // On Tick Handler ...
void OnTick() void OnTick()
{ {
//
HandleStrategiesOnTick(); HandleStrategiesOnTick();
//
HandleTradeState();
} }
// //
// On Timer ... // On Timer ...
void OnTimer() void OnTimer()
{ {
// HandleTradeState();
// HandleStrategiesOnTick();
} }
// //
@@ -199,6 +206,14 @@ bool InitialEA()
return result; return result;
} }
//
// Create Trader Instance ...
eaTrader = new XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTradeHandler = new XSCXTradeHandler(eaTrader);
// //
XSymbolParser symbolParser; XSymbolParser symbolParser;
@@ -241,6 +256,7 @@ bool InitialEA()
eaR2R, // R2R ... eaR2R, // R2R ...
eaSlippage, eaSlippage,
magicNumber, magicNumber,
true, // Ignore Signal Execution
true, // Use TP SL Point true, // Use TP SL Point
false, // Use Max false, // Use Max
50, // eaTPPoint, // TP 50, // eaTPPoint, // TP
@@ -254,6 +270,7 @@ bool InitialEA()
); );
eurusdTestStrategy.SetAlertLogAlerts(true); eurusdTestStrategy.SetAlertLogAlerts(true);
eurusdTestStrategy.SetAlertEnableAlerts(true); eurusdTestStrategy.SetAlertEnableAlerts(true);
eurusdTestStrategy.AddSignalEventHandler(OnSignalRecieved);
RegisterStrategy(eurusdTestStrategy); RegisterStrategy(eurusdTestStrategy);
} }
} }
@@ -307,6 +324,67 @@ void HandleTradeState()
{ {
// //
// Implement All Trade States here ... // Implement All Trade States here ...
eaTradeHandler.UpdateData();
}
//
// All Signals from Strategies Comming Here for Execution or
// Analyzing ...
void OnSignalRecieved(XSignal &signal)
{
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
bool isExecuted = eaTrader.ExecuteSignal(
signal,
state //
);
//
if (isExecuted)
{
//
// Find Executed Signal Deal History ...
XDeal deals[];
double commission = 0;
int dealsCount = eaTrader.GetDeals(
deals,
signal.symbol,
signal.provider,
signal.period,
NULL,
DEAL_ENTRY_IN //
);
if (IsValidSize(dealsCount))
{
//
for (int i = 0; i < dealsCount; i++)
{
//
XDeal iDeal = deals[i];
if (iDeal.positionId == signal.positionId)
{
//
commission = iDeal.commission;
break;
}
}
}
//
// Add Signal to Trade Handler ...
eaTradeHandler.AddExecutedSignal(
signal,
commission //
);
//
string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") +
" Signal Provided by: " + signal.provider +
" on: " + signal.symbol +
" in: " + ToString(signal.period) +
" Executed Successfully ...";
Print(msg);
}
} }
// //
+358
View File
@@ -3379,9 +3379,367 @@ struct XSymbolPositions
// //
}; };
//
// an Structure for Holding Positions Data ...
struct XTradeData
{
//
datetime time; // Issue Time (Open Position)
string symbol; // Trading Symbol
double entry; // Entry Price
double volume; // Volume
string provider; // Signaller
ENUM_TIMEFRAMES period; // Trading Timeframe
ENUM_X_POSITION_TYPES type; // Position Type
//
ulong ticket; // Position Ticket
double profit; // Profit on Close
double commission; // Commission
double swap; // Swap
string message; // Close Reason
datetime endTime; // End Time
//
// Constructor ...
void XTradeInfo()
{
Clean();
}
//
// Filling Trade Handler ...
bool Fill(XSignal &_signal)
{
//
bool result = false;
//
Clean();
//
// Check Signal Validation ...
result = _signal.IsValid();
if (!result)
{
return result;
}
//
time = _signal.time;
symbol = _signal.symbol;
entry = _signal.entry;
volume = _signal.volume;
provider = _signal.provider;
period = _signal.period;
type = ToPositionType(_signal.type);
//
if (_signal.IsExecuted())
{
ticket = _signal.positionId;
}
//
return result;
}
//
// Filling Trade Handler ...
bool Fill(XPosition &_position)
{
//
bool result = false;
//
Clean();
//
// Check Signal Validation ...
result = _position.IsValid();
if (!result)
{
return result;
}
//
time = _position.openAt;
symbol = _position.symbol;
entry = _position.entry;
volume = _position.volume;
provider = _position.provider;
period = _position.period;
type = ToPositionType(_position.type);
//
ticket = _position.ticket;
//
return result;
}
//
// Update Data ...
bool Update(XPosition &_position) {
//
bool result = false;
//
result = _position.IsValid();
if (!result) {
return result;
}
//
profit = _position.profit;
swap = _position.swap;
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
time = NULL;
type = NULL;
symbol = NULL;
period = NULL;
endTime = NULL;
message = NULL;
provider = NULL;
//
swap = 0;
entry = 0;
ticket = 0;
profit = 0;
volume = 0;
commission = 0;
}
//
// Validation ...
bool IsValid()
{
//
bool result = false;
//
result =
//
ticket > 0 &&
IsValid(time) &&
IsValid(symbol) &&
IsValid(period)
//
;
//
return result;
}
//
// Retrieve Trade Data Age ...
int GetAge()
{
//
int result = -1;
//
if (!IsValid(symbol) ||
!IsValid(time) ||
!IsValid(endTime) ||
!IsValid(period))
{
return result;
}
//
int startIndex = iBarShift(
symbol,
period,
time,
false //
);
//
int endIndex = iBarShift(
symbol,
period,
endTime,
false //
);
//
result = MathAbs(startIndex - endIndex);
//
return result;
}
//
// Check Own of Trade Data ...
// based on Ticket ...
bool IsOwn(
ulong _ticket //
)
{
//
bool result = false;
//
result = _ticket == ticket;
//
return result;
}
//
// Check Own of Trade Data ...
// based on Symbol/Provider and Period ...
bool IsOwn(
string _symbol,
string _provider,
ENUM_TIMEFRAMES _period,
ENUM_X_POSITION_TYPES _type //
)
{
//
bool result = false;
//
result =
//
IsValid(_symbol) &&
IsValid(_period) &&
IsValid(_provider) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE &&
//
type == _type &&
period == _period &&
symbol == _symbol &&
provider == _provider
//
;
//
return result;
}
//
// Data Collector ...
//
// Get Data File Name ...
string GetFileName()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
result =
//
symbol + "\\" +
ToString(type) + "\\" +
(profit >= 0 ? "Profit" : "Loss") +
ToString(ticket) + "_" +
ToString(period) + "_" +
ToFormatString(time)
//
;
//
return result;
}
//
// Get Signal File Name ...
string GetSignalFileName()
{
//
string result = NULL;
//
result =
//
symbol + "\\" +
ToString(type) + "\\" +
provider + "_" +
ToFormatString(time)
//
;
//
return result;
}
//
// Convert(s) To String Representation(s) ...
string ToString(
bool onlySignals = false //
)
{
//
string result = NULL;
//
int age = GetAge();
//
result =
//
(onlySignals ? "" : ToString("Ticket", ticket)) +
ToString("Symbol", symbol) +
ToString("Period", period) +
ToString("Entry", entry) +
ToString("Provider", provider) +
ToString("Type", ToString(type)) +
ToString("Time", time) +
(onlySignals
? ""
:
//
"-------------" + "\n" +
ToString("Volume", volume) +
ToString("Profit", profit) +
ToString("Commission", commission) +
ToString("Swap", swap) +
ToString("End Time", endTime) +
ToString("Age", age) +
ToString("Message", message)
//
) +
//
""
//
;
//
return result;
}
//
};
// //
// TypeDefs ... // TypeDefs ...
//
typedef void (*TOnSignal)(XSignal &signal);
// //
typedef void (*TOnDealsChanged)(int count); typedef void (*TOnDealsChanged)(int count);
+2
View File
@@ -59,6 +59,7 @@ public:
double _r2r, // Risk/Reward Ratio double _r2r, // Risk/Reward Ratio
int _slippage, // Trader Slippage int _slippage, // Trader Slippage
long _magicNumber, // Trader Magic Number long _magicNumber, // Trader Magic Number
bool _ignoreSignalExecution = false, // Ignore Signal Execution
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
double _tpPoint = 0, // TP As Point double _tpPoint = 0, // TP As Point
@@ -75,6 +76,7 @@ public:
_r2r, _r2r,
_slippage, _slippage,
_magicNumber, _magicNumber,
_ignoreSignalExecution,
_useTPSLAsPoint, _useTPSLAsPoint,
_forceMaxTPSLAsPoint, _forceMaxTPSLAsPoint,
_tpPoint, _tpPoint,