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-alert.class.mq5"
#include "../Classes/x-saherelm.x-chart.helper.class.mq5" #include "../Classes/x-saherelm.x-chart.helper.class.mq5"
#include "../Classes/x-saherelm.x-guard.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-target.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Classes/x-saherelm.x-volume.class.mq5" #include "../Classes/x-saherelm.x-volume.class.mq5"
@@ -82,9 +83,10 @@ class XCBackTesterEA : public XCBase
double volume; // Default volume Per Trade ... double volume; // Default volume Per Trade ...
// //
XCAlert *eaAlert; // EA Scope Alert Handler ... XCAlert *eaAlert; // EA Scope Alert Handler ...
XCTrade *eaTrader; // EA Scope Trade Handler ... XCTrade *eaTrader; // EA Scope Trade Handler ...
XCTarget *eaTarget; // EA Scope Target Manager ... XCTarget *eaTarget; // EA Scope Target Manager ...
XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ...
// //
XCChartHelper *eaChartHelper; // Chart Helper Class ... XCChartHelper *eaChartHelper; // Chart Helper Class ...
@@ -295,6 +297,10 @@ class XCBackTesterEA : public XCBase
// Init Target Managers ... // Init Target Managers ...
eaTarget = new XCTarget(eaTrader, eaAlert); eaTarget = new XCTarget(eaTrader, eaAlert);
//
// Init Position Drawer ...
eaPositionDrawer = new XCPositionDrawer(eaTrader);
// //
// Initial GUI ... // Initial GUI ...
result = InitGUI(); result = InitGUI();
@@ -321,6 +327,11 @@ class XCBackTesterEA : public XCBase
delete eaTarget; delete eaTarget;
ZeroMemory(eaTarget); ZeroMemory(eaTarget);
//
eaPositionDrawer.Destroy();
delete eaPositionDrawer;
ZeroMemory(eaPositionDrawer);
// //
delete eaTrader; delete eaTrader;
ZeroMemory(eaTrader); ZeroMemory(eaTrader);
@@ -359,6 +370,10 @@ class XCBackTesterEA : public XCBase
// //
// Managing Targets ... // Managing Targets ...
eaTarget.Manage(); eaTarget.Manage();
//
// Manage Positions Drawings ...
eaPositionDrawer.Update();
} }
/** /**
@@ -430,6 +445,9 @@ class XCBackTesterEA : public XCBase
// //
eaTarget.HandleOnStopLossTriggered(deal); eaTarget.HandleOnStopLossTriggered(deal);
//
eaPositionDrawer.HandleStopLossTriggered(deal);
} }
/** /**
@@ -445,6 +463,9 @@ class XCBackTesterEA : public XCBase
// //
eaTarget.HandleOnTakeProfitTriggered(deal); eaTarget.HandleOnTakeProfitTriggered(deal);
//
eaPositionDrawer.HandleOnTakeProfitTriggered(deal);
} }
/** /**
@@ -470,6 +491,13 @@ class XCBackTesterEA : public XCBase
position, position,
comment // comment //
); );
//
eaPositionDrawer.HandleOnPositionForceClosed(
ticket,
position,
comment //
);
} }
/** /**
@@ -572,7 +600,11 @@ class XCBackTesterEA : public XCBase
*/ */
void HandleOnSignalExecuted(XSignal &signal) void HandleOnSignalExecuted(XSignal &signal)
{ {
//
eaTarget.AddExecutedSignal(signal); eaTarget.AddExecutedSignal(signal);
//
eaPositionDrawer.AddExecutedSignal(signal);
} }
// //
+27
View File
@@ -1945,6 +1945,33 @@ class XCPositionObject : public XCBaseObject
return result; 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 ... // Checkers ...
+178 -8
View File
@@ -40,18 +40,25 @@ class XCPositionDrawer : public XCBase
public: public:
// //
// Props ... // Props ...
int window;
ulong chartID;
XCTrade *trader; XCTrade *trader;
CArrayObj positionObjects; CArrayObj positionObjects;
CArrayObj finalizedObjects;
// //
// Constructor ... // Constructor ...
XCPositionDrawer( XCPositionDrawer(
XCTrade *_trader // XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
) : XCBase() ) : XCBase()
{ {
// //
Init( Init(
_trader // _trader,
_chartID,
_window //
); );
} }
@@ -66,12 +73,17 @@ class XCPositionDrawer : public XCBase
// Tools ... // Tools ...
void Init( void Init(
XCTrade *_trader // XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
) )
{ {
// //
// Validate ... // Validate ...
bool has = _trader != NULL; bool has =
_window >= 0 &&
_chartID >= 0 &&
_trader != NULL;
if (!has) if (!has)
{ {
return; return;
@@ -79,6 +91,8 @@ class XCPositionDrawer : public XCBase
// //
trader = _trader; trader = _trader;
window = _window;
chartID = _chartID;
} }
void Destroy() void Destroy()
@@ -107,12 +121,66 @@ class XCPositionDrawer : public XCBase
// //
// Validate ... // Validate ...
bool has = IsValid(); bool has = IsValid();
if (!has) { if (!has)
{
return; 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 ... // Validate ...
if (!signal.IsValid() || !signal.IsExecuted()) bool has =
signal.IsValid() &&
signal.IsExecuted();
if (!has)
{ {
return; 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 ... * @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) void HandleOnTakeProfitTriggered(const XDeal &deal)
{ {
Finalize(deal.positionId);
} }
/** /**
@@ -164,6 +276,7 @@ class XCPositionDrawer : public XCBase
const string comment // const string comment //
) )
{ {
Finalize(ticket);
} }
// //
@@ -171,6 +284,63 @@ class XCPositionDrawer : public XCBase
protected: 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 ...
private: private: