last works on Position Drawer Class and Implement it on EA Backtester Expert Class ...

required to Test it's work ...
This commit is contained in:
2025-10-06 18:56:20 +03:30
parent f15e58fbc4
commit 8cc1ca21da
3 changed files with 240 additions and 11 deletions
@@ -24,6 +24,7 @@
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-chart.helper.class.mq5"
#include "../Classes/x-saherelm.x-guard.class.mq5"
#include "../Classes/x-saherelm.x-position.drawer.class.mq5"
#include "../Classes/x-saherelm.x-target.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Classes/x-saherelm.x-volume.class.mq5"
@@ -82,9 +83,10 @@ class XCBackTesterEA : public XCBase
double volume; // Default volume Per Trade ...
//
XCAlert *eaAlert; // EA Scope Alert Handler ...
XCTrade *eaTrader; // EA Scope Trade Handler ...
XCTarget *eaTarget; // EA Scope Target Manager ...
XCAlert *eaAlert; // EA Scope Alert Handler ...
XCTrade *eaTrader; // EA Scope Trade Handler ...
XCTarget *eaTarget; // EA Scope Target Manager ...
XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ...
//
XCChartHelper *eaChartHelper; // Chart Helper Class ...
@@ -295,6 +297,10 @@ class XCBackTesterEA : public XCBase
// Init Target Managers ...
eaTarget = new XCTarget(eaTrader, eaAlert);
//
// Init Position Drawer ...
eaPositionDrawer = new XCPositionDrawer(eaTrader);
//
// Initial GUI ...
result = InitGUI();
@@ -321,6 +327,11 @@ class XCBackTesterEA : public XCBase
delete eaTarget;
ZeroMemory(eaTarget);
//
eaPositionDrawer.Destroy();
delete eaPositionDrawer;
ZeroMemory(eaPositionDrawer);
//
delete eaTrader;
ZeroMemory(eaTrader);
@@ -359,6 +370,10 @@ class XCBackTesterEA : public XCBase
//
// Managing Targets ...
eaTarget.Manage();
//
// Manage Positions Drawings ...
eaPositionDrawer.Update();
}
/**
@@ -430,6 +445,9 @@ class XCBackTesterEA : public XCBase
//
eaTarget.HandleOnStopLossTriggered(deal);
//
eaPositionDrawer.HandleStopLossTriggered(deal);
}
/**
@@ -445,6 +463,9 @@ class XCBackTesterEA : public XCBase
//
eaTarget.HandleOnTakeProfitTriggered(deal);
//
eaPositionDrawer.HandleOnTakeProfitTriggered(deal);
}
/**
@@ -470,6 +491,13 @@ class XCBackTesterEA : public XCBase
position,
comment //
);
//
eaPositionDrawer.HandleOnPositionForceClosed(
ticket,
position,
comment //
);
}
/**
@@ -572,7 +600,11 @@ class XCBackTesterEA : public XCBase
*/
void HandleOnSignalExecuted(XSignal &signal)
{
//
eaTarget.AddExecutedSignal(signal);
//
eaPositionDrawer.AddExecutedSignal(signal);
}
//
+27
View File
@@ -1945,6 +1945,33 @@ class XCPositionObject : public XCBaseObject
return result;
}
//
// Retrievers ...
bool GetPosition(XPosition &_position)
{
//
bool result = false;
//
// Prepare ...
_position.Clean();
//
// Validate ...
result = HasPosition();
if (!result)
{
return result;
}
//
_position = mPosition;
//
return result;
}
//
// Checkers ...
+178 -8
View File
@@ -40,18 +40,25 @@ class XCPositionDrawer : public XCBase
public:
//
// Props ...
int window;
ulong chartID;
XCTrade *trader;
CArrayObj positionObjects;
CArrayObj finalizedObjects;
//
// Constructor ...
XCPositionDrawer(
XCTrade *_trader //
XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
) : XCBase()
{
//
Init(
_trader //
_trader,
_chartID,
_window //
);
}
@@ -66,12 +73,17 @@ class XCPositionDrawer : public XCBase
// Tools ...
void Init(
XCTrade *_trader //
XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
)
{
//
// Validate ...
bool has = _trader != NULL;
bool has =
_window >= 0 &&
_chartID >= 0 &&
_trader != NULL;
if (!has)
{
return;
@@ -79,6 +91,8 @@ class XCPositionDrawer : public XCBase
//
trader = _trader;
window = _window;
chartID = _chartID;
}
void Destroy()
@@ -107,12 +121,66 @@ class XCPositionDrawer : public XCBase
//
// Validate ...
bool has = IsValid();
if (!has) {
if (!has)
{
return;
}
//
// Update Exists Positions ...
XPosition positions[];
int positionsCount = trader.GetPositions(positions);
has = IsValidSize(positionsCount);
if (has)
{
//
int drawingsCount = positionObjects.Total();
has = IsValidSize(drawingsCount);
if (has)
{
for (int i = 0; i < positionsCount; i++)
{
//
for (int j = 0; j < drawingsCount; j++)
{
//
// Check Object is Belong to Position ...
has = ((XCPositionObject *)positionObjects.At(j)).IsBelong(positions[i]);
if (has)
{
((XCPositionObject *)positionObjects.At(j)).Update(positions[i]);
}
}
}
}
}
//
// Update Test Positions ...
positionsCount = positionObjects.Total();
has =
!HasChild(positions) &&
IsValidSize(positionsCount);
if (has)
{
//
XPosition iPosition;
for (int i = 0; i < positionsCount; i++)
{
//
// Retrieve Position from Object ...
has = ((XCPositionObject *)positionObjects.At(i)).GetPosition(iPosition);
if (has)
{
//
// Manully Update Position ...
((XCPositionObject *)positionObjects.At(i)).Update(barIndex);
}
}
//
iPosition.Clean();
}
}
//
@@ -127,10 +195,52 @@ class XCPositionDrawer : public XCBase
{
//
// Validate ...
if (!signal.IsValid() || !signal.IsExecuted())
bool has =
signal.IsValid() &&
signal.IsExecuted();
if (!has)
{
return;
}
//
XPosition iPosition;
//
// Check Position Exists ...
has = trader.GetPosition(
signal.positionId,
iPosition //
);
//
// Initial by Testing Position ...
if (!has)
{
//
has = ToXPosition(
signal,
iPosition,
trader.GetMagicNumber(),
signal.positionId //
);
}
//
// Validate result ...
if (has)
{
//
XCPositionObject *iObj;
has = iObj.Create(
chartID,
window,
iPosition //
);
}
//
// Cleanup Resources ...
iPosition.Clean();
}
/**
@@ -138,8 +248,9 @@ class XCPositionDrawer : public XCBase
*
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
*/
void HandleOnStopLossTriggered(const XDeal &deal)
void HandleStopLossTriggered(const XDeal &deal)
{
Finalize(deal.positionId);
}
/**
@@ -149,6 +260,7 @@ class XCPositionDrawer : public XCBase
*/
void HandleOnTakeProfitTriggered(const XDeal &deal)
{
Finalize(deal.positionId);
}
/**
@@ -164,6 +276,7 @@ class XCPositionDrawer : public XCBase
const string comment //
)
{
Finalize(ticket);
}
//
@@ -171,6 +284,63 @@ class XCPositionDrawer : public XCBase
protected:
//
//
void Finalize(ulong ticket)
{
//
int index = FindIndex(ticket);
bool has = IsValidIndex(index);
if (!has)
{
return;
}
//
XCPositionObject *iObj = positionObjects.At(index);
positionObjects.Delete(index);
finalizedObjects.Add(iObj);
}
int FindIndex(ulong ticket)
{
//
int result = -1;
//
// Validate ...
int count =
NotEmptyZero(ticket) &&
positionObjects.Total();
bool has = IsValidSize(count);
if (!has)
{
return result;
}
//
XPosition iPosition;
for (int i = 0; i < count; i++)
{
//
has = ((XCPositionObject *)positionObjects.At(i)).GetPosition(iPosition);
has = has &&
iPosition.ticket == ticket;
if (has)
{
//
result = i;
break;
}
}
//
// Cleanup Resources ...
iPosition.Clean();
//
return result;
}
//
// Private ...
private: