/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCPositionDrawer // Description: Provides Position // Drawing Tools ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-cobject.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5" #include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... // // Implementation ... class XCPositionDrawer : public XCBase { // // Public ... public: // // Props ... int window; ulong chartID; XCTrade *trader; CArrayObj positionObjects; CArrayObj finalizedObjects; // // Constructor ... XCPositionDrawer( XCTrade *_trader, ulong _chartID = 0, int _window = 0 // ) : XCBase() { // Init( _trader, _chartID, _window // ); } // // Deconstructor ... ~XCPositionDrawer() { Destroy(); } // // Tools ... void Init( XCTrade *_trader, ulong _chartID = 0, int _window = 0 // ) { // // Validate ... bool has = _window >= 0 && _chartID >= 0 && _trader != NULL; if (!has) { return; } // trader = _trader; window = _window; chartID = _chartID; } void Destroy() { } bool IsValid() { // bool result = false; // result = trader != NULL; // return result; } void Update(int barIndex = 0) { // // Normalize ... barIndex = NormalizeInt(barIndex, 0); // // Validate ... bool has = IsValid(); 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(); } } // // Trade Event Handlers ... /** * Add Executed Signal ... * * @param signal: XSignal, reference to Executed Signal ... */ void AddExecutedSignal(XSignal &signal) { // // Validate ... 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(); } /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleStopLossTriggered(const XDeal &deal) { Finalize(deal.positionId); } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnTakeProfitTriggered(const XDeal &deal) { Finalize(deal.positionId); } /** * Handle Position Force Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param position: XPosition instance refrence, Triggered Position ... * @param comment: string, Comment ... */ void HandleOnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { Finalize(ticket); } // // 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: // // }; //