### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.base.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XBaseClass // Description: provides all based classes for use ... // // // 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 // #include "../Libraries/x-saherelm.common.lib.mq5" // // XBase Class ... class XCBase { // // Public ... public: // // Protected ... // // Represent Basic Unique Tag ... virtual string GetTag() { return NULL; } // // Retrieve Class Token ... virtual string GetToken() { return NULL; } // // Protected protected: // // Private ... private: }; // template string GenerateSpecifiedCommonSummary( T &mItem, string separator = "\n", bool includeScores = true, bool setLabel = false // ) { // string result = NULL; // double bullishScore = 0; double bearishScore = 0; mItem.GenerateScore( bullishScore, bearishScore // ); // result = // (!setLabel ? "" : "Commons:" + separator) + "---------------" + separator + "Symbol: " + mItem.symbol + separator + "Period: " + ToXString(mItem.period) + separator + "Time: " + ToXString(mItem.time) + separator + (includeScores ? "---------------" + separator + "Scores:" + separator + "---------------" + separator + "Bullish: " + ToXString(bullishScore) + separator + "Bearish: " + ToXString(bearishScore) + separator + "---------------" + separator : "") + "" // ; // return result; } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.session-detector.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCSessionDetector // Description: Forex Session Detector with Event System // // 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 Forex Session Detector Class" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Libraries/x-saherelm.common.extensions.lib.mq5" #include "../Libraries/x-saherelm.x-enums.lib.mq5" // // Definitions ... // #region Session Types ... // // Forex Session Types ... enum ENUM_X_SESSION_TYPE { X_SESSION_NONE = 0, // None X_SESSION_SYDNEY = 1, // Sydney Session X_SESSION_TOKYO = 2, // Tokyo Session X_SESSION_LONDON = 3, // London Session X_SESSION_NEWYORK = 4, // New York Session X_SESSION_FRANKFURT = 5, // Frankfurt Session X_SESSION_SINGAPORE = 6, // Singapore Session X_SESSION_HONGKONG = 7, // Hong Kong Session }; /** * Validate ... * * @param value: ENUM_X_SESSION_TYPE member ... * * @return ( bool ) */ bool IsValid(ENUM_X_SESSION_TYPE value) { // bool result = false; // result = value != NULL && value != X_SESSION_NONE; // return result; } bool IsXValid(ENUM_X_SESSION_TYPE value) { return IsValid(value); } /** * Cpnverts to String ... * * @param value: ENUM_X_SESSION_TYPE ... * * @return ( string ) */ string ToXString(ENUM_X_SESSION_TYPE value) { // string result = NULL; // if (value == NULL) { return result; } // switch (value) { // case X_SESSION_NONE: result = "NONE"; break; // case X_SESSION_SYDNEY: result = "SYDNEY"; break; // case X_SESSION_TOKYO: result = "TOKYO"; break; // case X_SESSION_LONDON: result = "LONDON"; break; // case X_SESSION_NEWYORK: result = "NEWYORK"; break; // case X_SESSION_FRANKFURT: result = "FRANKFURT"; break; // case X_SESSION_SINGAPORE: result = "SINGAPORE"; break; // case X_SESSION_HONGKONG: result = "HONGKONG"; break; } // return result; } /** * Parse From String ... * * @param value: string ... * * @return ( ENUM_X_SESSION_TYPE ) */ ENUM_X_SESSION_TYPE FromXString(string value) { // ENUM_X_SESSION_TYPE result = X_SESSION_NONE; // // Validate ... if (!IsXValid(value)) { return result; } // if (value == ToXString(X_SESSION_NONE)) { result = X_SESSION_NONE; } else if (value == ToXString(X_SESSION_SYDNEY)) { result = X_SESSION_SYDNEY; } else if (value == ToXString(X_SESSION_TOKYO)) { result = X_SESSION_TOKYO; } else if (value == ToXString(X_SESSION_LONDON)) { result = X_SESSION_LONDON; } else if (value == ToXString(X_SESSION_NEWYORK)) { result = X_SESSION_NEWYORK; } else if (value == ToXString(X_SESSION_FRANKFURT)) { result = X_SESSION_FRANKFURT; } else if (value == ToXString(X_SESSION_SINGAPORE)) { result = X_SESSION_SINGAPORE; } else if (value == ToXString(X_SESSION_HONGKONG)) { result = X_SESSION_HONGKONG; } // return result; } // #endregion // #region Session Overlap Types ... // // Session Overlap Types ... enum ENUM_X_SESSION_OVERLAP_TYPE { X_OVERLAP_NONE = 0, // None X_OVERLAP_SYDNEY_TOKYO = 1, // Sydney-Tokyo Overlap X_OVERLAP_TOKYO_LONDON = 2, // Tokyo-London Overlap X_OVERLAP_LONDON_NEWYORK = 3, // London-New York Overlap (Most Liquid) X_OVERLAP_LONDON_FRANKFURT = 4, // London-Frankfurt Overlap X_OVERLAP_NEWYORK_SYDNEY = 5, // New York-Sydney Overlap X_OVERLAP_TOKYO_SINGAPORE = 6, // Tokyo-Singapore Overlap X_OVERLAP_HONGKONG_TOKYO = 7, // Hong Kong-Tokyo Overlap }; /** * Validate ... * * @param value: ENUM_X_SESSION_OVERLAP_TYPE member ... * * @return ( bool ) */ bool IsValid(ENUM_X_SESSION_OVERLAP_TYPE value) { // bool result = false; // result = value != NULL && value != X_OVERLAP_NONE; // return result; } bool IsXValid(ENUM_X_SESSION_OVERLAP_TYPE value) { return IsValid(value); } /** * Cpnverts to String ... * * @param value: ENUM_X_SESSION_OVERLAP_TYPE ... * * @return ( string ) */ string ToXString(ENUM_X_SESSION_OVERLAP_TYPE value) { // string result = NULL; // // Validate ... if (value == NULL) { return result; } // switch (value) { // case X_OVERLAP_NONE: result = "NONE"; break; // case X_OVERLAP_SYDNEY_TOKYO: result = "SYDNEY_TOKYO"; break; // case X_OVERLAP_TOKYO_LONDON: result = "TOKYO_LONDON"; break; // case X_OVERLAP_LONDON_NEWYORK: result = "LONDON_NEWYORK"; break; // case X_OVERLAP_LONDON_FRANKFURT: result = "LONDON_FRANKFURT"; break; // case X_OVERLAP_NEWYORK_SYDNEY: result = "NEWYORK_SYDNEY"; break; // case X_OVERLAP_TOKYO_SINGAPORE: result = "TOKYO_SINGAPORE"; break; // case X_OVERLAP_HONGKONG_TOKYO: result = "HONGKONG_TOKYO"; break; } // return result; } // #endregion // #region Session State ... // // Session State ... enum ENUM_X_SESSION_STATE { X_SESSION_STATE_INACTIVE = 0, // Session Not Active X_SESSION_STATE_ACTIVE = 1, // Session Active X_SESSION_STATE_STARTING = 2, // Session Starting (First Bar) X_SESSION_STATE_ENDING = 3, // Session Ending (Last Bar) }; /** * Check a Session State is Active or not ... * * @param value: ENUM_X_SESSION_STATE * * @return ( bool ) */ bool IsXActive(ENUM_X_SESSION_STATE value) { // bool result = false; // result = value == X_SESSION_STATE_ACTIVE; // return result; } // #endregion // #region Event Handler Types ... typedef void (*TOnSessionStart)(ENUM_X_SESSION_TYPE session, datetime startTime); typedef void (*TOnSessionEnd)(ENUM_X_SESSION_TYPE session, datetime endTime); typedef void (*TOnOverlapStart)(ENUM_X_SESSION_OVERLAP_TYPE overlap, datetime startTime); typedef void (*TOnOverlapEnd)(ENUM_X_SESSION_OVERLAP_TYPE overlap, datetime endTime); typedef void (*TOnSessionStateChange)(ENUM_X_SESSION_TYPE session, ENUM_X_SESSION_STATE state); // #endregion // #region Session Configuration ... struct XSessionConfig { // string name; // Session Name ENUM_X_SESSION_TYPE type; // Session Type string startTime; // Start Time (HH:MM) string endTime; // End Time (HH:MM) color sessionColor; // Session Color for Visualization bool isActive; // Is Session Active datetime lastStartTime; // Last Start Time datetime lastEndTime; // Last End Time ENUM_X_SESSION_STATE state; // Current State // // Constructor ... XSessionConfig() { Clean(); } // // Tools ... // void Clean() { // name = NULL; type = X_SESSION_NONE; startTime = NULL; endTime = NULL; sessionColor = CLR_NONE; isActive = false; lastStartTime = NULL; lastEndTime = NULL; state = X_SESSION_STATE_INACTIVE; // ZeroMemory(this); } // void Default(ENUM_X_SESSION_TYPE _type) { // Clean(); // // Validate ... if (!IsXValid(_type)) { return; } // type = _type; name = ToXString(_type); // switch (_type) { // case X_SESSION_SYDNEY: startTime = "22:00"; endTime = "07:00"; sessionColor = clrAqua; break; // case X_SESSION_TOKYO: startTime = "00:00"; endTime = "09:00"; sessionColor = clrYellow; break; // case X_SESSION_SINGAPORE: startTime = "01:00"; endTime = "09:00"; sessionColor = clrOrange; break; // case X_SESSION_HONGKONG: startTime = "01:00"; endTime = "09:00"; sessionColor = clrGold; break; // case X_SESSION_FRANKFURT: startTime = "07:00"; endTime = "16:00"; sessionColor = clrLime; break; // case X_SESSION_LONDON: startTime = "08:00"; endTime = "17:00"; sessionColor = clrGreen; break; // case X_SESSION_NEWYORK: startTime = "13:00"; endTime = "22:00"; sessionColor = clrRed; break; // default: name = "Unknown"; startTime = "00:00"; endTime = "00:00"; sessionColor = clrGray; break; } } // bool IsValid() { // bool result = false; // result = IsXValid(type) && IsXValid(name) && IsXValid(startTime) && IsXValid(endTime); // return result; } }; // #endregion // #region Overlap Configuration ... struct XOverlapConfig { // string name; // Overlap Name ENUM_X_SESSION_OVERLAP_TYPE type; // Overlap Type ENUM_X_SESSION_TYPE session1; // First Session ENUM_X_SESSION_TYPE session2; // Second Session string overlapStartTime; // Overlap Start Time string overlapEndTime; // Overlap End Time color overlapColor; // Overlap Color bool isActive; // Is Overlap Active datetime lastStartTime; // Last Start Time datetime lastEndTime; // Last End Time // // Constructor ... XOverlapConfig() { Clean(); } // // Tools ... // void Clean() { // name = NULL; type = X_OVERLAP_NONE; session1 = X_SESSION_NONE; session2 = X_SESSION_NONE; overlapStartTime = NULL; overlapEndTime = NULL; overlapColor = CLR_NONE; isActive = false; lastStartTime = NULL; lastEndTime = NULL; // ZeroMemory(this); } // void Default(ENUM_X_SESSION_OVERLAP_TYPE _type) { // Clean(); // if (!IsXValid(_type)) { return; } // type = _type; name = ToXString(_type); // switch (_type) { // case X_OVERLAP_SYDNEY_TOKYO: session1 = X_SESSION_SYDNEY; session2 = X_SESSION_TOKYO; overlapStartTime = "00:00"; overlapEndTime = "07:00"; overlapColor = clrYellow; break; // case X_OVERLAP_TOKYO_LONDON: session1 = X_SESSION_TOKYO; session2 = X_SESSION_LONDON; overlapStartTime = "08:00"; overlapEndTime = "09:00"; overlapColor = clrLime; break; // case X_OVERLAP_LONDON_NEWYORK: session1 = X_SESSION_LONDON; session2 = X_SESSION_NEWYORK; overlapStartTime = "13:00"; overlapEndTime = "17:00"; overlapColor = clrOrange; break; // case X_OVERLAP_LONDON_FRANKFURT: session1 = X_SESSION_LONDON; session2 = X_SESSION_FRANKFURT; overlapStartTime = "08:00"; overlapEndTime = "16:00"; overlapColor = clrGreen; break; // case X_OVERLAP_NEWYORK_SYDNEY: session1 = X_SESSION_NEWYORK; session2 = X_SESSION_SYDNEY; overlapStartTime = "22:00"; overlapEndTime = "22:00"; overlapColor = clrPurple; break; // case X_OVERLAP_TOKYO_SINGAPORE: session1 = X_SESSION_TOKYO; session2 = X_SESSION_SINGAPORE; overlapStartTime = "01:00"; overlapEndTime = "09:00"; overlapColor = clrGold; break; // case X_OVERLAP_HONGKONG_TOKYO: session1 = X_SESSION_HONGKONG; session2 = X_SESSION_TOKYO; overlapStartTime = "01:00"; overlapEndTime = "09:00"; overlapColor = clrPink; break; // default: name = "Unknown"; session1 = X_SESSION_NONE; session2 = X_SESSION_NONE; overlapStartTime = "00:00"; overlapEndTime = "00:00"; overlapColor = clrGray; break; } } // bool IsValid() { // bool result = false; // result = IsXValid(type) && IsXValid(name) && IsXValid(session1) && IsXValid(session2); // return result; } }; // #endregion // // Implementation ... class XCSessionDetector : public XCBase { // public: // // Props ... // XCAlert *alert; // Alert Handler XSessionConfig sessions[]; // All Sessions XOverlapConfig overlaps[]; // All Overlaps // // Event Handlers ... TOnSessionEnd mOnSessionEndHandlers[]; TOnOverlapEnd mOnOverlapEndHandlers[]; TOnSessionStart mOnSessionStartHandlers[]; TOnOverlapStart mOnOverlapStartHandlers[]; TOnSessionStateChange mOnSessionStateChangeHandlers[]; // // Time Tracking ... datetime lastCheckTime; // Last Check Time int timezoneOffset; // Timezone Offset (in Hours) bool useServerTime; // Use Server Time or UTC // // Constructor ... XCSessionDetector( XCAlert *_alert = NULL, bool _useServerTime = true, int _timezoneOffset = 0 // ) { alert = _alert; useServerTime = _useServerTime; timezoneOffset = _timezoneOffset; lastCheckTime = NULL; // InitializeSessions(); InitializeOverlaps(); } // // Deconstructor ... ~XCSessionDetector() { // Clean(sessions); Clean(overlaps); Clean(mOnSessionEndHandlers); Clean(mOnOverlapEndHandlers); Clean(mOnSessionStartHandlers); Clean(mOnOverlapStartHandlers); Clean(mOnSessionStateChangeHandlers); // ZeroMemory(alert); } // #region Getters ... /** * Get Session Config by Type * * @param sessionType: ENUM_X_SESSION_TYPE * * @return ( XSessionConfig ) */ XSessionConfig GetSessionConfig(ENUM_X_SESSION_TYPE sessionType) { // XSessionConfig result; result.Clean(); // if (!IsXValid(sessionType)) { return result; } // int sessionsCount = ArraySize(sessions); for (int i = 0; i < sessionsCount; i++) { // if (sessions[i].type == sessionType) { result = sessions[i]; break; } } // return result; } /** * Get Overlap Config by Type * * @param overlapType: ENUM_X_SESSION_OVERLAP_TYPE * * @return ( XOverlapConfig ) */ XOverlapConfig GetOverlapConfig(ENUM_X_SESSION_OVERLAP_TYPE overlapType) { // XOverlapConfig result; result.Clean(); // if (!IsXValid(overlapType)) { return result; } // int overlapsCount = ArraySize(overlaps); for (int i = 0; i < overlapsCount; i++) { // if (overlaps[i].type == overlapType) { result = overlaps[i]; break; } } // return result; } /** * Get Current Active Session * * @param currentTime: datetime * * @return ( ENUM_X_SESSION_TYPE ) */ ENUM_X_SESSION_TYPE GetCurrentSession(datetime currentTime = NULL) { // ENUM_X_SESSION_TYPE result = X_SESSION_NONE; // if (!IsXValid(currentTime)) { currentTime = GetCurrentTime(); } // int sessionsCount = ArraySize(sessions); for (int i = 0; i < sessionsCount; i++) { // if (IsSessionActive(sessions[i].type, currentTime)) { result = sessions[i].type; break; } } // return result; } /** * Get Current Active Overlap * * @param currentTime: datetime * * @return ( ENUM_X_SESSION_OVERLAP_TYPE ) */ ENUM_X_SESSION_OVERLAP_TYPE GetCurrentOverlap(datetime currentTime = NULL) { // ENUM_X_SESSION_OVERLAP_TYPE result = X_OVERLAP_NONE; // if (!IsXValid(currentTime)) { currentTime = GetCurrentTime(); } // int overlapsCount = ArraySize(overlaps); for (int i = 0; i < overlapsCount; i++) { // if (IsOverlapActive(overlaps[i], currentTime)) { result = overlaps[i].type; break; } } // return result; } // #endregion // #region Tools & Actions ... /** * Initialize All Forex Sessions */ void InitializeSessions() { // Clean(sessions); // // Sydney Session XSessionConfig sydney; sydney.Default(X_SESSION_SYDNEY); AddRef(sydney, sessions); // // Tokyo Session XSessionConfig tokyo; tokyo.Default(X_SESSION_TOKYO); AddRef(tokyo, sessions); // // Singapore Session XSessionConfig singapore; singapore.Default(X_SESSION_SINGAPORE); AddRef(singapore, sessions); // // Hong Kong Session XSessionConfig hongkong; hongkong.Default(X_SESSION_HONGKONG); AddRef(hongkong, sessions); // // Frankfurt Session XSessionConfig frankfurt; frankfurt.Default(X_SESSION_FRANKFURT); AddRef(frankfurt, sessions); // // London Session XSessionConfig london; london.Default(X_SESSION_LONDON); AddRef(london, sessions); // // New York Session XSessionConfig newyork; newyork.Default(X_SESSION_NEWYORK); AddRef(newyork, sessions); } /** * Initialize All Session Overlaps */ void InitializeOverlaps() { // Clean(overlaps); // // Sydney-Tokyo Overlap XOverlapConfig sydneyTokyo; sydneyTokyo.Default(X_OVERLAP_SYDNEY_TOKYO); AddRef(sydneyTokyo, overlaps); // // Tokyo-London Overlap XOverlapConfig tokyoLondon; tokyoLondon.Default(X_OVERLAP_TOKYO_LONDON); AddRef(tokyoLondon, overlaps); // // London-New York Overlap (Most Important) XOverlapConfig londonNewYork; londonNewYork.Default(X_OVERLAP_LONDON_NEWYORK); AddRef(londonNewYork, overlaps); // // London-Frankfurt Overlap XOverlapConfig londonFrankfurt; londonFrankfurt.Default(X_OVERLAP_LONDON_FRANKFURT); AddRef(londonFrankfurt, overlaps); // // New York-Sydney Overlap XOverlapConfig newyorkSydney; newyorkSydney.Default(X_OVERLAP_NEWYORK_SYDNEY); AddRef(newyorkSydney, overlaps); } /** * Get Current Time (Adjusted for Timezone) * * @return ( datetime ) */ datetime GetCurrentTime() { // datetime currentTime = useServerTime ? TimeCurrent() : TimeGMT(); // if (timezoneOffset != 0) { currentTime = (datetime)((int)currentTime + (timezoneOffset * 3600)); } // return currentTime; } /** * Parse Time String to DateTime (Today's Date + Time) * * @param timeString: String (HH:MM format) * @param baseDate: datetime (Base Date) * * @return ( datetime ) */ datetime ParseTimeToDateTime( string timeString, datetime baseDate // ) { // datetime result = NULL; // if (!IsXValid(timeString)) { return result; } // MqlDateTime dt; TimeToStruct(baseDate, dt); // string parts[]; int partsCount = SplitContent(parts, timeString, ":"); if (partsCount >= 2) { // dt.hour = (int)parts[0]; dt.min = (int)parts[1]; dt.sec = 0; // result = StructToTime(dt); } // return result; } /** * Check if Current Time is Within Session Time Range * * @param startTime: String (HH:MM) * @param endTime: String (HH:MM) * @param currentTime: datetime * * @return ( bool ) */ bool IsTimeInRange( string startTime, string endTime, datetime currentTime // ) { // bool result = false; // if (!IsXValid(startTime) || !IsXValid(endTime)) { return result; } // datetime todayStart = ParseTimeToDateTime(startTime, currentTime); datetime todayEnd = ParseTimeToDateTime(endTime, currentTime); // // Handle Sessions that Cross Midnight if (todayEnd < todayStart) { // // Session crosses midnight result = (currentTime >= todayStart || currentTime < todayEnd); } else { // // Normal session result = (currentTime >= todayStart && currentTime < todayEnd); } // return result; } /** * Check if Current Time is Within Overlap Time Range * * @param overlap: XOverlapConfig reference * @param currentTime: datetime * * @return ( bool ) */ bool IsOverlapActive( XOverlapConfig &overlap, datetime currentTime // ) { // bool result = false; // if (!overlap.IsValid()) { return result; } // // Check if Both Sessions are Active bool session1Active = IsSessionActive(overlap.session1, currentTime); bool session2Active = IsSessionActive(overlap.session2, currentTime); // result = session1Active && session2Active; // return result; } /** * Check if Specific Session is Active * * @param sessionType: ENUM_X_SESSION_TYPE * @param currentTime: datetime * * @return ( bool ) */ bool IsSessionActive( ENUM_X_SESSION_TYPE sessionType, datetime currentTime // ) { // bool result = false; // int sessionsCount = ArraySize(sessions); for (int i = 0; i < sessionsCount; i++) { // if (sessions[i].type == sessionType) { // result = IsTimeInRange( sessions[i].startTime, sessions[i].endTime, currentTime // ); // break; } } // return result; } /** * Get Active Sessions * * @param activeSessions: ENUM_X_SESSION_TYPE collection reference * @param currentTime: datetime * * @return ( int ) */ int GetActiveSessions( ENUM_X_SESSION_TYPE &activeSessions[], datetime currentTime = NULL // ) { // int result = 0; Clean(activeSessions); // if (!IsXValid(currentTime)) { currentTime = GetCurrentTime(); } // int sessionsCount = ArraySize(sessions); for (int i = 0; i < sessionsCount; i++) { // if (IsSessionActive(sessions[i].type, currentTime)) { Add(sessions[i].type, activeSessions); } } // result = ArraySize(activeSessions); // return result; } /** * Get Active Overlaps * * @param activeOverlaps: ENUM_X_SESSION_OVERLAP_TYPE collection reference * @param currentTime: datetime * * @return ( int ) */ int GetActiveOverlaps( ENUM_X_SESSION_OVERLAP_TYPE &activeOverlaps[], datetime currentTime = NULL // ) { // int result = 0; Clean(activeOverlaps); // if (!IsXValid(currentTime)) { currentTime = GetCurrentTime(); } // int overlapsCount = ArraySize(overlaps); for (int i = 0; i < overlapsCount; i++) { // if (IsOverlapActive(overlaps[i], currentTime)) { Add(overlaps[i].type, activeOverlaps); } } // result = ArraySize(activeOverlaps); // return result; } // #endregion // #region Processors ... /** * Process Session Detection (Call on Every Tick or Bar) * * @param currentTime: datetime (Optional, uses current time if NULL) */ void Process(datetime currentTime = NULL) { // if (!IsXValid(currentTime)) { currentTime = GetCurrentTime(); } // // Check if Enough Time Passed Since Last Check (Prevent Multiple Fires) if (IsXValid(lastCheckTime) && (int)currentTime - (int)lastCheckTime < 60) // Minimum 1 minute between checks { return; } // lastCheckTime = currentTime; // // Process All Sessions int sessionsCount = ArraySize(sessions); for (int i = 0; i < sessionsCount; i++) { ProcessSession(sessions[i], currentTime); } // // Process All Overlaps int overlapsCount = ArraySize(overlaps); for (int i = 0; i < overlapsCount; i++) { ProcessOverlap(overlaps[i], currentTime); } } /** * Process Individual Session * * @param session: XSessionConfig reference * @param currentTime: datetime */ void ProcessSession( XSessionConfig &session, datetime currentTime // ) { // if (!session.IsValid()) { return; } // bool wasActive = session.isActive; bool isActive = IsTimeInRange( session.startTime, session.endTime, currentTime // ); // // Session Started if (isActive && !wasActive) { // session.isActive = true; session.lastStartTime = currentTime; session.state = X_SESSION_STATE_STARTING; // NotifySessionStart(session.type, currentTime); NotifySessionStateChange(session.type, session.state); // // Log Alert if (alert != NULL) { // string message = "Session Started: " + session.name + " at " + TimeToString(currentTime, TIME_DATE | TIME_SECONDS); // alert.SendAlert(message); } } // // Session Ended else if (!isActive && wasActive) { // session.isActive = false; session.lastEndTime = currentTime; session.state = X_SESSION_STATE_ENDING; // NotifySessionEnd(session.type, currentTime); NotifySessionStateChange(session.type, session.state); // // Log Alert if (alert != NULL) { // string message = "Session Ended: " + session.name + " at " + TimeToString(currentTime, TIME_DATE | TIME_SECONDS); // alert.SendAlert(message); } } // // Session Active (Ongoing) else if (isActive && wasActive) { session.state = X_SESSION_STATE_ACTIVE; } // // Session Inactive else { session.state = X_SESSION_STATE_INACTIVE; } } /** * Process Individual Overlap * * @param overlap: XOverlapConfig reference * @param currentTime: datetime */ void ProcessOverlap( XOverlapConfig &overlap, datetime currentTime // ) { // if (!overlap.IsValid()) { return; } // bool wasActive = overlap.isActive; bool isActive = IsOverlapActive(overlap, currentTime); // // Overlap Started if (isActive && !wasActive) { // overlap.isActive = true; overlap.lastStartTime = currentTime; // NotifyOverlapStart(overlap.type, currentTime); // // Log Alert if (alert != NULL) { // string message = "Overlap Started: " + overlap.name + " at " + TimeToString(currentTime, TIME_DATE | TIME_SECONDS); // alert.SendAlert(message); } } // // Overlap Ended else if (!isActive && wasActive) { // overlap.isActive = false; overlap.lastEndTime = currentTime; // NotifyOverlapEnd(overlap.type, currentTime); // // Log Alert if (alert != NULL) { // string message = "Overlap Ended: " + overlap.name + " at " + TimeToString(currentTime, TIME_DATE | TIME_SECONDS); // alert.SendAlert(message); } } } // #endregion // #region Event Listener Registration ... /** * Add Session Start Event Handler * * @param handler: TOnSessionStart */ void AddOnSessionStartHandler(TOnSessionStart handler) { // if (handler == NULL) { return; } // Add(handler, mOnSessionStartHandlers); } /** * Add Session End Event Handler * * @param handler: TOnSessionEnd */ void AddOnSessionEndHandler(TOnSessionEnd handler) { // if (handler == NULL) { return; } // Add(handler, mOnSessionEndHandlers); } /** * Add Overlap Start Event Handler * * @param handler: TOnOverlapStart */ void AddOnOverlapStartHandler(TOnOverlapStart handler) { // if (handler == NULL) { return; } // Add(handler, mOnOverlapStartHandlers); } /** * Add Overlap End Event Handler * * @param handler: TOnOverlapEnd */ void AddOnOverlapEndHandler(TOnOverlapEnd handler) { // if (handler == NULL) { return; } // Add(handler, mOnOverlapEndHandlers); } /** * Add Session State Change Event Handler * * @param handler: TOnSessionStateChange */ void AddOnSessionStateChangeHandler(TOnSessionStateChange handler) { // if (handler == NULL) { return; } // Add(handler, mOnSessionStateChangeHandlers); } // #endregion // protected: // // #region Event Notifiers ... /** * Notify Session Start Event * * @param session: ENUM_X_SESSION_TYPE * @param startTime: datetime */ void NotifySessionStart( ENUM_X_SESSION_TYPE session, datetime startTime // ) { // // Validate ... if (!IsXValid(session)) { return; } // // Multiple Handlers ... int count = ArraySize(mOnSessionStartHandlers); for (int i = 0; i < count; i++) { // mOnSessionStartHandlers[i]( session, startTime // ); } } /** * Notify Session End Event * * @param session: ENUM_X_SESSION_TYPE * @param endTime: datetime */ void NotifySessionEnd( ENUM_X_SESSION_TYPE session, datetime endTime // ) { // // Validate ... if (!IsXValid(session)) { return; } // // Multiple Handlers ... int count = ArraySize(mOnSessionEndHandlers); for (int i = 0; i < count; i++) { // mOnSessionEndHandlers[i]( session, endTime // ); } } /** * Notify Overlap Start Event * * @param overlap: ENUM_X_SESSION_OVERLAP_TYPE * @param startTime: datetime */ void NotifyOverlapStart( ENUM_X_SESSION_OVERLAP_TYPE overlap, datetime startTime // ) { // // Validate ... if (!IsXValid(overlap)) { return; } // // Multiple Handlers ... int count = ArraySize(mOnOverlapStartHandlers); for (int i = 0; i < count; i++) { // mOnOverlapStartHandlers[i]( overlap, startTime // ); } } /** * Notify Overlap End Event * * @param overlap: ENUM_X_SESSION_OVERLAP_TYPE * @param endTime: datetime */ void NotifyOverlapEnd( ENUM_X_SESSION_OVERLAP_TYPE overlap, datetime endTime // ) { // // Validate ... if (!IsXValid(overlap)) { return; } // // Multiple Handlers ... int count = ArraySize(mOnOverlapEndHandlers); for (int i = 0; i < count; i++) { // mOnOverlapEndHandlers[i]( overlap, endTime // ); } } /** * Notify Session State Change Event * * @param session: ENUM_X_SESSION_TYPE * @param state: ENUM_X_SESSION_STATE */ void NotifySessionStateChange( ENUM_X_SESSION_TYPE session, ENUM_X_SESSION_STATE state // ) { // // Validate ... if (!IsXValid(session)) { return; } // // Multiple Handlers ... int count = ArraySize(mOnSessionStateChangeHandlers); for (int i = 0; i < count; i++) { // mOnSessionStateChangeHandlers[i]( session, state); } } // #endregion private: // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-account.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCAccount // Description: provides all Account requirements ... // // // 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 // // START Definitions ... // // // END Definitions ... // // // START Import and Inclused requirements ... // // // Includes ... #include "../Classes/x-saherelm.base.class.mq5" #include // // END Import and Inclused requirements ... // // // START Overrides ... // // // END Overrides ... // // // a Class for Manage Account ... class XCAccount : public XCBase { // // Public ... public: // // Constructor ... XCAccount() { // mAccountInfo = new CAccountInfo(); } // // Deconstructor ... ~XCAccount() { } // // START Provided Functions ... // // // User Account ... long GetUserAccount() { return mAccountInfo.Login(); } // // Account Leverage ... long GetLeverage() { return mAccountInfo.Leverage(); } // // Get Trade Expert State ... bool CanExpertTrade() { return mAccountInfo.TradeExpert(); } // // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... // -------------------------- // ACCOUNT_TRADE_MODE_DEMO // ACCOUNT_TRADE_MODE_CONTEST // ACCOUNT_TRADE_MODE_REAL ENUM_ACCOUNT_TRADE_MODE GetTradeMode() { return mAccountInfo.TradeMode(); } // // Get Account Balance ... double GetBalance() { return mAccountInfo.Balance(); } // // Get the amount of give Credit ... double GetCredit() { return mAccountInfo.Credit(); } // // Get the amount of current Profit on account ... double GetProfit() { return mAccountInfo.Profit(); } // // Get the amount of current Equity on account ... double GetEquity() { return mAccountInfo.Equity(); } // // Get the amount of reserved Margin ... double GetMargin() { return mAccountInfo.Margin(); } // // Get the amount of free Margin ... double GetFreeMargin() { return mAccountInfo.FreeMargin(); } // // Get the Level of Margin ... double GetMarginLevel() { return mAccountInfo.MarginLevel(); } // // Get the Level Of Margin for a Deposit ... double GetMarginCall() { return mAccountInfo.MarginCall(); } // // Get the Level of Margin for Stop out ... double GetMarginStopOut() { return mAccountInfo.MarginStopOut(); } // // Get the Client Name ... string GetName() { return mAccountInfo.Name(); } // // Get the Trade Server Name ... string GetServerName() { return mAccountInfo.Server(); } // // Get deposit Currency Name ... string GetCurrency() { return mAccountInfo.Currency(); } // // Get the Company Name that serves an Account ... string GetCompany() { return mAccountInfo.Company(); } // // Calculate Profits for the current account based on passed parameters ... double CalculateTradeProfit( const string symbol, // trading symbol ENUM_ORDER_TYPE type, // order type double volume, // volume double entry, // open price double exit // close price ) { // double result = mAccountInfo.OrderProfitCheck( symbol, type, volume, entry, exit); // return result; } // // Calculate amount of margin which required for trade operation ... double CalculateMarging( const string symbol, // trading symbol ENUM_ORDER_TYPE type, // order type double volume, // volume double entry // open price ) { // double result = mAccountInfo.MarginCheck( symbol, type, volume, entry); // return result; } // // Calculate amount of free margin left after trade operation ... double CalculateFreeMarging( const string symbol, // trading symbol ENUM_ORDER_TYPE type, // order type double volume, // volume double entry // open price ) { // double result = mAccountInfo.FreeMarginCheck( symbol, type, volume, entry); // return result; } // // Calculate the Maximum possible volume of trade operation ... double CalculateMaxVolume( const string symbol, // trading symbol ENUM_ORDER_TYPE type, // order type double entry, // open price double percent = 100 // percent of available margin ) { // double result = mAccountInfo.MaxLotCheck( symbol, type, entry, percent); // return result; } // // Calculate Point Value for Given Symbol based on Account ... double GetPointValue( string symbol // trading symbol ) { // double result = 0; // double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); double point = SymbolInfoDouble(symbol, SYMBOL_POINT); // double ticksPerPoint = tickSize / point; // result = tickValue / ticksPerPoint; // return result; } // // Calculate Risk Amount based on account Currency by Providing: // Points and Volume ... double CalculateRiskAmount( string symbol, // trading symbol double points, // amount of Risk Points double volume // position Volume ) { // double result = 0; // double pointValue = GetPointValue(symbol); // result = pointValue * volume * points; // return result; } // // Calculate Risk Points based on account Currency by Providing: // Volume and Amount ... double CalculateRiskPoints( string symbol, // trading symbol double volume, // position Volume double amount // amount of Risk based on Account Currency ) { // double result = 0; // double pointValue = GetPointValue(symbol); // result = amount / (pointValue * volume); // return result; } // // Calculate Volume based on account Currency by Providing: // Amount and Risk Points ... double CalculateVolume( string symbol, // trading symbol double amount, // amount of Risk based on Account Currency double points // amount of Risk Points ) { // double result = 0; // points = points <= 0 ? 10 : points; // double pointValue = GetPointValue(symbol); // result = amount / (pointValue * points); // return result; } /** * Retrieve Specified Message for Report Balance ... * * @return ( string ) */ string GetBalanceReportMessage() { return "Balance: " + ToXString(GetBalance()) + " " + GetCurrency(); } // // END Provided Functions ... // // // Protected ... protected: // // Private ... private: // // Account Info ... CAccountInfo mAccountInfo; }; // // START Usefull Functions ... // // // END Usefull Functions ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-alert.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCAlert // Description: provides all Alerts requirements ... // // // 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-data.collector.class.mq5" // // Class Definition ... class XCAlert : public XCBase { // // Public ... public: // // Props ... // // Constructor ... XCAlert( string prefix = "X-Alert", // Alerts Prefixe bool enableAlerts = true, // Enable Alerts bool logAlerts = true, // Log Alerts bool terminalAlerts = false, // Terminal Alerts bool mailAlerts = false, // Mail Alerts bool pushAlerts = false, // Push Alerts bool saveAlerts = false // Save Alerts ) { // mPrefix = prefix; mLogAlerts = logAlerts; mMailAlerts = mailAlerts; mPushAlerts = pushAlerts; mSaveAlerts = saveAlerts; mEnableAlerts = enableAlerts; mTerminalAlerts = terminalAlerts; // // Normalize Prefix if Not Provided ... if (!IsValid(mPrefix)) { mPrefix = GetTag(); } // // Initialize Collector ... collector = new XCDataCollector(); collector.Path(mPrefix); } // // Deconstructor ... ~XCAlert() { // // Cleanup Resources ... delete collector; ZeroMemory(collector); } // // Override ... string GetTag() override { return GetSpecificToken(this); } // #region Properties Getter(s) / Setter(s) ... // string GetPrefix() { return mPrefix; } // void SetPrefix(string value) { // mPrefix = value; collector.Path(mPrefix); } // bool GetLogAlerts() { return mLogAlerts; } // void SetLogAlerts(bool value) { mLogAlerts = value; } // bool GetEnableAlerts() { return mEnableAlerts; } // void SetEnableAlerts(bool value) { mEnableAlerts = value; } // bool GetSaveAlerts() { return mSaveAlerts; } // void SetSaveAlerts(bool value) { mSaveAlerts = value; } // bool GetPushAlerts() { return mPushAlerts; } // void SetPushAlerts(bool value) { mPushAlerts = value; } // bool GetMailAlerts() { return mMailAlerts; } // void SetMailAlerts(bool value) { mMailAlerts = value; } // bool GetTerminalAlerts() { return mTerminalAlerts; } // void SetTerminalAlerts(bool value) { mTerminalAlerts = value; } // #endregion // #region Tools Funtions ... // // Alerts ... // // Logging an Alert ... void LogAlert(string message, bool save = true) { // // Validate Args ... if (!CanLogAlert()) { return; } // message = PrepareMessage(message); // Log(message); // if (save) { Save(message); } } // // Terminal Alert ... void TerminalAlert(string message, bool save = true) { // // Validate Args ... if (!CanTerminalAlert()) { return; } // // Prepare Message ... message = PrepareMessage(message); // Send Terminal Alert ... Alert(message); // if (save) { Save(message); } } // // Mail Alert ... void MailAlert(string message, bool save = true) { // // Validate Args ... if (!CanMailAlert()) { return; } // // Send Mail Alert ... SendMail(GetPrefix(), message); // if (save) { Save(message); } } // // Send Push Notification ... void PushAlert(string message, bool save = true) { // // Validate Args ... if (!CanPushAlert()) { return; } // // Prepare Message ... message = PrepareMessage(message); // // Send Push Notification Alert ... SendNotification(message); // if (save) { Save(message); } } // // Send an Alert by Handling all Different Specified // type's of Alert's if they are Enabled ... void SendAlert(string message) { // // Handle Log, if Enabled ... LogAlert(message, false); // // Handle Mail if Enabled ... MailAlert(message, false); // // Handle Push if Enabled ... PushAlert(message, false); // // Handle Terminal if Enabled ... TerminalAlert(message, false); // if (GetEnableAlerts()) { Save(message); } } // // Logs ... // // Log a Message ... void Log(string message) { // if (!CanLog()) { return; } // Print(message); } void Log(string tag, string message) { // if (!CanLog()) { return; } // Print(GetPrefix(), "_", tag, " > ", message); } void LogEmpty() { // if (!CanLog()) { return; } // Print(" "); } // // Log Specific Array ... template void LogArray( T &array[], // Array to Log string label = NULL // Array Label ) { // if (!CanLog()) { return; } // Print(GetPrefix(), ">", (IsValid(label) ? label : "")); ArrayPrint(array); } // // Error ... // // Log an Error ... void LogError( int error = -1 // Specific Error, if it's equal to -1, use Last Error ... ) { // if (!CanLog()) { return; } // if (error <= -1) { error = GetLastError(); } // string errorMsg = GetErrorDescription(error); // Log("Error: " + errorMsg); } // // Retrieve Specified Error Code Description ... string GetErrorDescription(int err_code) { // string result = ""; // switch (err_code) { // //--- Constant Description // case ERR_SUCCESS: result = "The operation completed successfully"; break; // case ERR_INTERNAL_ERROR: result = "Unexpected internal error"; break; // case ERR_WRONG_INTERNAL_PARAMETER: result = "Wrong parameter in the inner call of the client terminal function"; break; // case ERR_INVALID_PARAMETER: result = "Wrong parameter when calling the system function"; break; // case ERR_NOT_ENOUGH_MEMORY: result = "Not enough memory to perform the system function"; break; // case ERR_STRUCT_WITHOBJECTS_ORCLASS: result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; break; // case ERR_INVALID_ARRAY: result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; break; // case ERR_ARRAY_RESIZE_ERROR: result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; break; // case ERR_STRING_RESIZE_ERROR: result = "Not enough memory for the relocation of string"; break; // case ERR_NOTINITIALIZED_STRING: result = "Not initialized string"; break; // case ERR_INVALID_DATETIME: result = "Invalid date and/or time"; break; // case ERR_ARRAY_BAD_SIZE: result = "Requested array size exceeds 2 GB"; break; // case ERR_INVALID_POINTER: result = "Wrong pointer"; break; // case ERR_INVALID_POINTER_TYPE: result = "Wrong type of pointer"; break; // case ERR_FUNCTION_NOT_ALLOWED: result = "System function is not allowed to call"; break; // //--- Charts // case ERR_CHART_WRONG_ID: result = "Wrong chart ID"; break; // case ERR_CHART_NO_REPLY: result = "Chart does not respond"; break; // case ERR_CHART_NOT_FOUND: result = "Chart not found"; break; // case ERR_CHART_NO_EXPERT: result = "No Expert Advisor in the chart that could handle the event"; break; // case ERR_CHART_CANNOT_OPEN: result = "Chart opening error"; break; // case ERR_CHART_CANNOT_CHANGE: result = "Failed to change chart symbol and period"; break; // case ERR_CHART_CANNOT_CREATE_TIMER: result = "Failed to create timer"; break; // case ERR_CHART_WRONG_PROPERTY: result = "Wrong chart property ID"; break; // case ERR_CHART_SCREENSHOT_FAILED: result = "Error creating screenshots"; break; // case ERR_CHART_NAVIGATE_FAILED: result = "Error navigating through chart"; break; // case ERR_CHART_TEMPLATE_FAILED: result = "Error applying template"; break; // case ERR_CHART_WINDOW_NOT_FOUND: result = "Subwindow containing the indicator was not found"; break; // case ERR_CHART_INDICATOR_CANNOT_ADD: result = "Error adding an indicator to chart"; break; // case ERR_CHART_INDICATOR_CANNOT_DEL: result = "Error deleting an indicator from the chart"; break; // case ERR_CHART_INDICATOR_NOT_FOUND: result = "Indicator not found on the specified chart"; break; // //--- Graphical Objects case ERR_OBJECT_ERROR: result = "Error working with a graphical object"; break; // case ERR_OBJECT_NOT_FOUND: result = "Graphical object was not found"; break; // case ERR_OBJECT_WRONG_PROPERTY: result = "Wrong ID of a graphical object property"; break; // case ERR_OBJECT_GETDATE_FAILED: result = "Unable to get date corresponding to the value"; break; // case ERR_OBJECT_GETVALUE_FAILED: result = "Unable to get value corresponding to the date"; break; // //--- MarketInfo // case ERR_MARKET_UNKNOWN_SYMBOL: result = "Unknown symbol"; break; // case ERR_MARKET_NOT_SELECTED: result = "Symbol is not selected in MarketWatch"; break; // case ERR_MARKET_WRONG_PROPERTY: result = "Wrong identifier of a symbol property"; break; // case ERR_MARKET_LASTTIME_UNKNOWN: result = "Time of the last tick is not known (no ticks)"; break; // case ERR_MARKET_SELECT_ERROR: result = "Error adding or deleting a symbol in MarketWatch"; break; // //--- History Access // case ERR_HISTORY_NOT_FOUND: result = "Requested history not found"; break; // case ERR_HISTORY_WRONG_PROPERTY: result = "Wrong ID of the history property"; break; // //--- Global_Variables // case ERR_GLOBALVARIABLE_NOT_FOUND: result = "Global variable of the client terminal is not found"; break; // case ERR_GLOBALVARIABLE_EXISTS: result = "Global variable of the client terminal with the same name already exists"; break; // case ERR_MAIL_SEND_FAILED: result = "Email sending failed"; break; // case ERR_PLAY_SOUND_FAILED: result = "Sound playing failed"; break; // case ERR_MQL5_WRONG_PROPERTY: result = "Wrong identifier of the program property"; break; // case ERR_TERMINAL_WRONG_PROPERTY: result = "Wrong identifier of the terminal property"; break; // case ERR_FTP_SEND_FAILED: result = "File sending via ftp failed"; break; // case ERR_NOTIFICATION_SEND_FAILED: result = "Error in sending notification"; break; // //--- Custom Indicator Buffers // case ERR_BUFFERS_NO_MEMORY: result = "Not enough memory for the distribution of indicator buffers"; break; // case ERR_BUFFERS_WRONG_INDEX: result = "Wrong indicator buffer index"; break; // //--- Custom Indicator Properties // case ERR_CUSTOM_WRONG_PROPERTY: result = "Wrong ID of the custom indicator property"; break; // //--- Account // case ERR_ACCOUNT_WRONG_PROPERTY: result = "Wrong account property ID"; break; // case ERR_TRADE_WRONG_PROPERTY: result = "Wrong trade property ID"; break; // case ERR_TRADE_DISABLED: result = "Trading by Expert Advisors prohibited"; break; // case ERR_TRADE_POSITION_NOT_FOUND: result = "Position not found"; break; // case ERR_TRADE_ORDER_NOT_FOUND: result = "Order not found"; break; // case ERR_TRADE_DEAL_NOT_FOUND: result = "Deal not found"; break; // case ERR_TRADE_SEND_FAILED: result = "Trade request sending failed"; break; // //--- Indicators // case ERR_INDICATOR_UNKNOWN_SYMBOL: result = "Unknown symbol"; break; // case ERR_INDICATOR_CANNOT_CREATE: result = "Indicator cannot be created"; break; // case ERR_INDICATOR_NO_MEMORY: result = "Not enough memory to add the indicator"; break; // case ERR_INDICATOR_CANNOT_APPLY: result = "The indicator cannot be applied to another indicator"; break; // case ERR_INDICATOR_CANNOT_ADD: result = "Error applying an indicator to chart"; break; // case ERR_INDICATOR_DATA_NOT_FOUND: result = "Requested data not found"; break; // case ERR_INDICATOR_WRONG_HANDLE: result = "Wrong indicator handle"; break; // case ERR_INDICATOR_WRONG_PARAMETERS: result = "Wrong number of parameters when creating an indicator"; break; // case ERR_INDICATOR_PARAMETERS_MISSING: result = "No parameters when creating an indicator"; break; // case ERR_INDICATOR_CUSTOM_NAME: result = "The first parameter in the array must be the name of the custom indicator"; break; // case ERR_INDICATOR_PARAMETER_TYPE: result = "Invalid parameter type in the array when creating an indicator"; break; // case ERR_INDICATOR_WRONG_INDEX: result = "Wrong index of the requested indicator buffer"; break; // //--- Depth of Market // case ERR_BOOKS_CANNOT_ADD: result = "Depth Of Market can not be added"; break; // case ERR_BOOKS_CANNOT_DELETE: result = "Depth Of Market can not be removed"; break; // case ERR_BOOKS_CANNOT_GET: result = "The data from Depth Of Market can not be obtained"; break; // case ERR_BOOKS_CANNOT_SUBSCRIBE: result = "Error in subscribing to receive new data from Depth Of Market"; break; // //--- File Operations // case ERR_TOO_MANY_FILES: result = "More than 64 files cannot be opened at the same time"; break; // case ERR_WRONG_FILENAME: result = "Invalid file name"; break; // case ERR_TOO_LONG_FILENAME: result = "Too long file name"; break; // case ERR_CANNOT_OPEN_FILE: result = "File opening error"; break; // case ERR_FILE_CACHEBUFFER_ERROR: result = "Not enough memory for cache to read"; break; // case ERR_CANNOT_DELETE_FILE: result = "File deleting error"; break; // case ERR_INVALID_FILEHANDLE: result = "A file with this handle was closed, or was not opening at all"; break; // case ERR_WRONG_FILEHANDLE: result = "Wrong file handle"; break; // case ERR_FILE_NOTTOWRITE: result = "The file must be opened for writing"; break; // case ERR_FILE_NOTTOREAD: result = "The file must be opened for reading"; break; // case ERR_FILE_NOTBIN: result = "The file must be opened as a binary one"; break; // case ERR_FILE_NOTTXT: result = "The file must be opened as a text"; break; // case ERR_FILE_NOTTXTORCSV: result = "The file must be opened as a text or CSV"; break; // case ERR_FILE_NOTCSV: result = "The file must be opened as CSV"; break; // case ERR_FILE_READERROR: result = "File reading error"; break; // case ERR_FILE_BINSTRINGSIZE: result = "String size must be specified, because the file is opened as binary"; break; // case ERR_INCOMPATIBLE_FILE: result = "A text file must be for string arrays, for other arrays - binary"; break; // case ERR_FILE_IS_DIRECTORY: result = "This is not a file, this is a directory"; break; // case ERR_FILE_NOT_EXIST: result = "File does not exist"; break; // case ERR_FILE_CANNOT_REWRITE: result = "File can not be rewritten"; break; // case ERR_WRONG_DIRECTORYNAME: result = "Wrong directory name"; break; // case ERR_DIRECTORY_NOT_EXIST: result = "Directory does not exist"; break; // case ERR_FILE_ISNOT_DIRECTORY: result = "This is a file, not a directory"; break; // case ERR_CANNOT_DELETE_DIRECTORY: result = "The directory cannot be removed"; break; // case ERR_CANNOT_CLEAN_DIRECTORY: result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; break; // case ERR_FILE_WRITEERROR: result = "Failed to write a resource to a file"; break; // //--- String Casting // case ERR_NO_STRING_DATE: result = "No date in the string"; break; // case ERR_WRONG_STRING_DATE: result = "Wrong date in the string"; break; // case ERR_WRONG_STRING_TIME: result = "Wrong time in the string"; break; // case ERR_STRING_TIME_ERROR: result = "Error converting string to date"; break; // case ERR_STRING_OUT_OF_MEMORY: result = "Not enough memory for the string"; break; // case ERR_STRING_SMALL_LEN: result = "The string length is less than expected"; break; // case ERR_STRING_TOO_BIGNUMBER: result = "Too large number, more than ULONG_MAX"; break; // case ERR_WRONG_FORMATSTRING: result = "Invalid format string"; break; // case ERR_TOO_MANY_FORMATTERS: result = "Amount of format specifiers more than the parameters"; break; // case ERR_TOO_MANY_PARAMETERS: result = "Amount of parameters more than the format specifiers"; break; // case ERR_WRONG_STRING_PARAMETER: result = "Damaged parameter of string type"; break; // case ERR_STRINGPOS_OUTOFRANGE: result = "Position outside the string"; break; // case ERR_STRING_ZEROADDED: result = "0 added to the string end, a useless operation"; break; // case ERR_STRING_UNKNOWNTYPE: result = "Unknown data type when converting to a string"; break; // case ERR_WRONG_STRING_OBJECT: result = "Damaged string object"; break; // //--- Operations with Arrays // case ERR_INCOMPATIBLE_ARRAYS: result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; break; // case ERR_SMALL_ASSERIES_ARRAY: result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; break; // case ERR_SMALL_ARRAY: result = "Too small array, the starting position is outside the array"; break; // case ERR_ZEROSIZE_ARRAY: result = "An array of zero length"; break; // case ERR_NUMBER_ARRAYS_ONLY: result = "Must be a numeric array"; break; // case ERR_ONEDIM_ARRAYS_ONLY: result = "Must be a one-dimensional array"; break; // case ERR_SERIES_ARRAY: result = "Timeseries cannot be used"; break; // case ERR_DOUBLE_ARRAY_ONLY: result = "Must be an array of type double"; break; // case ERR_FLOAT_ARRAY_ONLY: result = "Must be an array of type float"; break; // case ERR_LONG_ARRAY_ONLY: result = "Must be an array of type long"; break; // case ERR_INT_ARRAY_ONLY: result = "Must be an array of type int"; break; // case ERR_SHORT_ARRAY_ONLY: result = "Must be an array of type short"; break; // case ERR_CHAR_ARRAY_ONLY: result = "Must be an array of type char"; break; // //--- Operations with OpenCL // case ERR_OPENCL_NOT_SUPPORTED: result = "OpenCL functions are not supported on this computer"; break; // case ERR_OPENCL_INTERNAL: result = "Internal error occurred when running OpenCL"; break; // case ERR_OPENCL_INVALID_HANDLE: result = "Invalid OpenCL handle"; break; // case ERR_OPENCL_CONTEXT_CREATE: result = "Error creating the OpenCL context"; break; // case ERR_OPENCL_QUEUE_CREATE: result = "Failed to create a run queue in OpenCL"; break; // case ERR_OPENCL_PROGRAM_CREATE: result = "Error occurred when compiling an OpenCL program"; break; // case ERR_OPENCL_TOO_LONG_KERNEL_NAME: result = "Too long kernel name (OpenCL kernel)"; break; // case ERR_OPENCL_KERNEL_CREATE: result = "Error creating an OpenCL kernel"; break; // case ERR_OPENCL_SET_KERNEL_PARAMETER: result = "Error occurred when setting parameters for the OpenCL kernel"; break; // case ERR_OPENCL_EXECUTE: result = "OpenCL program runtime error"; break; // case ERR_OPENCL_WRONG_BUFFER_SIZE: result = "Invalid size of the OpenCL buffer"; break; // case ERR_OPENCL_WRONG_BUFFER_OFFSET: result = "Invalid offset in the OpenCL buffer"; break; // case ERR_OPENCL_BUFFER_CREATE: result = "Failed to create and OpenCL buffer"; break; // //--- User-Defined Errors default: result = "UNKNOWN Erro ..."; break; } // return result; } // // Retrieve Specified Error Code Description ... string GetTradeServerReturnCodeDescription(int return_code) { // string result = ""; // switch (return_code) { // case TRADE_RETCODE_REQUOTE: result = "Requote"; break; // case TRADE_RETCODE_REJECT: result = "Request rejected"; break; // case TRADE_RETCODE_CANCEL: result = "Request canceled by trader"; break; // case TRADE_RETCODE_PLACED: result = "Order placed"; break; // case TRADE_RETCODE_DONE: result = "Request completed"; break; // case TRADE_RETCODE_DONE_PARTIAL: result = "Only part of the request was completed"; break; // case TRADE_RETCODE_ERROR: result = "Request processing error"; break; // case TRADE_RETCODE_TIMEOUT: result = "Request canceled by timeout"; break; // case TRADE_RETCODE_INVALID: result = "Invalid request"; break; // case TRADE_RETCODE_INVALID_VOLUME: result = "Invalid volume in the request"; break; // case TRADE_RETCODE_INVALID_PRICE: result = "Invalid price in the request"; break; // case TRADE_RETCODE_INVALID_STOPS: result = "Invalid stops in the request"; break; // case TRADE_RETCODE_TRADE_DISABLED: result = "Trade is disabled"; break; // case TRADE_RETCODE_MARKET_CLOSED: result = "Market is closed"; break; // case TRADE_RETCODE_NO_MONEY: result = "There is not enough money to complete the request"; break; // case TRADE_RETCODE_PRICE_CHANGED: result = "Prices changed"; break; // case TRADE_RETCODE_PRICE_OFF: result = "There are no quotes to process the request"; break; // case TRADE_RETCODE_INVALID_EXPIRATION: result = "Invalid order expiration date in the request"; break; // case TRADE_RETCODE_ORDER_CHANGED: result = "Order state changed"; break; // case TRADE_RETCODE_TOO_MANY_REQUESTS: result = "Too frequent requests"; break; // case TRADE_RETCODE_NO_CHANGES: result = "No changes in request"; break; // case TRADE_RETCODE_SERVER_DISABLES_AT: result = "Autotrading disabled by server"; break; // case TRADE_RETCODE_CLIENT_DISABLES_AT: result = "Autotrading disabled by client terminal"; break; // case TRADE_RETCODE_LOCKED: result = "Request locked for processing"; break; // case TRADE_RETCODE_FROZEN: result = "Order or position frozen"; break; // case TRADE_RETCODE_INVALID_FILL: result = "Invalid order filling type"; break; // case TRADE_RETCODE_CONNECTION: result = "No connection with the trade server"; break; // case TRADE_RETCODE_ONLY_REAL: result = "Operation is allowed only for live accounts"; break; // case TRADE_RETCODE_LIMIT_ORDERS: result = "The number of pending orders has reached the limit"; break; // case TRADE_RETCODE_LIMIT_VOLUME: result = "The volume of orders and positions for the symbol has reached the limit"; break; // default: result = "Invalid return code of the trade server"; break; } // return result; } // #endregion // // Protected ... protected: // // Private ... // bool CanLog() { return mLogAlerts; } // bool CanLogAlert() { // bool result = GetEnableAlerts() && GetLogAlerts(); // return result; } // bool CanTerminalAlert() { // bool result = GetEnableAlerts() && GetTerminalAlerts(); // return result; } // bool CanMailAlert() { // bool result = GetEnableAlerts() && GetMailAlerts(); // return result; } // bool CanPushAlert() { // bool result = GetEnableAlerts() && GetPushAlerts(); // return result; } // void Save(string message) { // if (!mSaveAlerts || !IsValid(message) || message == mLastSavedMessage || PrepareMessage(message) == mLastSavedMessage) { return; } // string fileName = mPrefix + "." + "XLogs"; string filePath = collector.GetFilePath(fileName); if (!IsValid(filePath)) { return; } // // Attach Time ... string savedMessage = ToXString(TimeCurrent()) + " " + message; // bool has = collector.Append( filePath, savedMessage // ); if (has) { mLastSavedMessage = message; } } private: // // Props ... string mPrefix; // Alerts Prefixe bool mEnableAlerts; // Enable Alerts bool mSaveAlerts; // Save Alerts bool mLogAlerts; // Log Alerts bool mTerminalAlerts; // Terminal Alerts bool mMailAlerts; // Mail Alerts bool mPushAlerts; // Push Alerts // string mLastSavedMessage; // For Prevent Multiple Saving Same Mesage ... XCDataCollector *collector; // // Tools ... // // Clear Escape String and // Attach Alert Prefix to Message ... string PrepareMessage(string message) { // StringReplace(message, "\n", " | "); // StringConcatenate(message, GetPrefix(), " > ", message); // return message; } }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-app-dialog.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCPanel // Description: provides all based classes for use ... // // // 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 // #include "../Classes/x-saherelm.base.class.mq5" // // Extentions ... /** * Check a Qery Contains in a Content or not ... * * @param mQuery: String ... * @param mContent: String ... * @param ignoreCase: Boolean ... * * @return ( bool ) */ bool XContains( string mQuery, // Search String string mContent, // Search Content bool ignoreCase = true // Ignore Case ) { return Contains( mQuery, mContent, ignoreCase // ); } // // Implementation ... // // a Base App Dialog Class ... class XCAppDialog : public CAppDialog { public: // // Action ... // // Virual ... /** * Override Close Button Click Action ... */ void OnClickButtonClose() { // bool isClosed = ConfirmDialog("Close EA ?"); // if (isClosed) { Destroy(); } } // // Configuration Actions ... /** * Show or Hide Minimize Button ... * * @param show: boolean */ void MinimizeButton(bool show) { // int controlIDX = ControlFind("MinMax"); if (!IsValidIndex(controlIDX)) { return; } // if (show) { Control(controlIDX).Show(); } else { Control(controlIDX).Hide(); } } /** * Show or Hide Close Button ... * * @param show: boolean */ void CloseButton(bool show) { // int controlIDX = ControlFind("Close"); if (!IsValidIndex(controlIDX)) { return; } // if (show) { Control(controlIDX).Show(); } else { Control(controlIDX).Hide(); } } /** * Minimize Functionality Implementation ... */ void Minimize() { // m_minimized = true; Rebound(m_min_rect); ClientAreaVisible(false); } /** * Set Background Color ... * * @param clr: Color ... */ void BackgroundColor(color clr) { // int controlIDX = ControlFind("Client"); if (!IsValidIndex(controlIDX)) { return; } // CWnd *obj = Control(controlIDX); CWndClient *wndclient = (CWndClient *)obj; // wndclient.ColorBackground(clr); } // // Overrides ... // protected: // /** * Find Specific Control in Dialog ... * * @param name: String to Search * * @return ( int ) */ int ControlFind(string name) { // int result = -1; // if (!IsValid(name)) { return result; } // int count = ControlsTotal(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // string iName = Control(i).Name(); // bool isContains = XContains( name, iName, true // Ignore Case ... ); if (isContains) { // result = i; break; } } // return result; } /** * Create and Run Confirm Dialog ... * * @param message: message for Message Box ... * * @return ( bool ) */ bool ConfirmDialog(string message = NULL) { // bool result = false; // if (!IsValid(message)) { message = "Confirm ?"; } // int dialogResult = MessageBox(message, NULL, MB_YESNO); // // use 'switch' or 'if' as needed switch (dialogResult) { // // Yes ... case IDYES: result = true; break; // // No ... case IDNO: result = false; break; // // Cancel ... case IDCANCEL: result = false; break; } // return result; } // private: // // }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-backtester.expert.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCBackTesterEA // Description: Back Tester Expert Class ... // // 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-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" // // Import Chart Objects ... #include #include #include #include #include #include #include #include #include #include #include // // Definitions ... // // Implementation ... class XCBackTesterEA : public XCBase { // // Public ... public: // // // Common ... long eaMagicNumber; // Magic Number int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix // // Symbol / Period ... string symbol; // Symbol ENUM_TIMEFRAMES period; // Period // // Volume ... ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type double eaStaticVoluem; // Static Volume double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume double eaDynamicVolumeStepVolume; // Step of Volume Increasing double eaConstantRiskBalance; // Constant Risk Balance per Trade double eaConstantPercent; // Constant Percent of Balance Per Trade double eaConstantBalance; // Constant Balance for Calculations // // Alert ... bool eaEnableAlerts; // Enable Alerts bool eaLogAlerts; // Log Alerts bool eaMailAlerts; // Mail Alerts bool eaPushAlerts; // Push Alerts bool eaTerminalAlerts; // Terminal Alerts // // SL/TP Manipulation Props ... double allowedTPSLStep; // Value for Change TP/SL in Each Step ... double minAllowedRiskInPoint; // Min Allowed Risk in Point ... double riskInPoint; // Risk in Point per Trades ... double riskToRewardRatio; // Risk To Reward per Trades ... double volume; // Default volume Per Trade ... // XCAlert *eaAlert; // EA Scope Alert Handler ... XCGuard *eaGuard; // EA Scope Guard Handler ... XCTrade *eaTrader; // EA Scope Trade Handler ... XCTarget *eaTarget; // EA Scope Target Manager ... XCVolume *eaVolume; // EA Scope Volume Manager ... XCChartHelper *eaChartHelper; // EA Chart Helper ... XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ... // // Constructor ... XCBackTesterEA() { // selectedPositionID = 0; // volume = 0.01; riskInPoint = 50; allowedTPSLStep = 5; riskToRewardRatio = 2; minAllowedRiskInPoint = 10; } // // Deconstructor ... ~XCBackTesterEA() { } // // Actions / Handlers ... // // Expert Advisor Event Handlers ... /** * Handle Initialization of Expert ... * * @return ( bool ) */ bool HandleOnInit() { // bool result = false; // // Validate Inputs ... result = ValidateInputs(); if (!result) { return result; } // int count = 0; bool has = false; // // Chart Helper ... eaChartHelper = new XCChartHelper(); // // Initialize Alert Handler ... eaAlert = new XCAlert(); eaAlert.SetPrefix(eaLogSuffix); eaAlert.SetLogAlerts(eaLogAlerts); eaAlert.SetMailAlerts(eaMailAlerts); eaAlert.SetPushAlerts(eaPushAlerts); eaAlert.SetEnableAlerts(eaEnableAlerts); eaAlert.SetTerminalAlerts(eaTerminalAlerts); // // Initialize Trader ... eaTrader = new XCTrade( eaSlippage, eaMagicNumber, 0, 0, 0 // ); // // Trade Handler Attachments ... // // Position Modifiy Event Handlers ... count = ArraySize(mOnModifyEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]); } } // // Position Stop Loss Event Handlers ... count = ArraySize(mStopLossEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnStopLossEventHandler(mStopLossEventHandlers[i]); } } // // Position Take Profit Event Handlers ... count = ArraySize(mTakeProfitEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]); } } // // Position Force Close Event Handlers ... count = ArraySize(mOnForceCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]); } } // // Deals Changed Event Handlers ... count = ArraySize(mDealsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]); } } // // Orders Changed Event Handlers ... count = ArraySize(mOrdersChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]); } } // // Positions Changed Event Handlers ... count = ArraySize(mPositionsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]); } } // // Trade Changed Event Handlers ... count = ArraySize(mTradeStateChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]); } } // // Postion Partially Close Event Handlers ... count = ArraySize(mOnPartialCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]); } } // // Signal Executed Event Handlers ... count = ArraySize(mOnSignalExecutedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnSignalExecutedEventHandler(mOnSignalExecutedEventHandlers[i]); } } // // Init Target Managers ... eaTarget = new XCTarget(eaTrader, eaAlert); // // Initialize Guard Handler ... eaGuard = new XCGuard( eaAlert, eaTrader // ); // eaVolume = new XCVolume(); result = eaVolume.Init( eaVolumeSelect, eaStaticVoluem, eaDynamicVolumeStepBalance, eaDynamicVolumeStepVolume, eaConstantRiskBalance, eaConstantPercent, eaConstantBalance // ); if (!result) { return result; } // // Init Position Drawer ... eaPositionDrawer = new XCPositionDrawer(eaTrader); // // Initial GUI ... result = InitGUI(); if (!result) { return result; } // // Normalize Requirements ... NormalizeProps(); // return result; } /** * Handle De Initialization of Expert ... */ void HandleOnDeInit() { // eaTarget.Destroy(); delete eaTarget; ZeroMemory(eaTarget); // if (eaPositionDrawer != NULL) { // eaPositionDrawer.Destroy(); delete eaPositionDrawer; ZeroMemory(eaPositionDrawer); } // delete eaVolume; ZeroMemory(eaVolume); // delete eaTrader; ZeroMemory(eaTrader); // delete eaGuard; ZeroMemory(eaGuard); // SpecifiedClean(mOnModifyEventHandlers); SpecifiedClean(mStopLossEventHandlers); SpecifiedClean(mTakeProfitEventHandlers); SpecifiedClean(mOnForceCloseEventHandlers); SpecifiedClean(mDealsChangedEventHandlers); SpecifiedClean(mOrdersChangedEventHandlers); SpecifiedClean(mOnPartialCloseEventHandlers); SpecifiedClean(mPositionsChangedEventHandlers); SpecifiedClean(mTradeStateChangedEventHandlers); // DestroyGUI(); // string message = "DeInitialized Successfully ..."; eaAlert.SendAlert(message); // delete eaAlert; ZeroMemory(eaAlert); } /** * Handle Tick ... */ void HandleOnTick() { // UpdateGUI(); // // Managing Targets ... eaTarget.Manage(); // // Manage Positions Drawings ... if (eaPositionDrawer != NULL) { eaPositionDrawer.Update(); } } /** * Handle Trade ... */ void HandleOnTrade() { eaTrader.HandleOnTrade(); } /** * Handle Timer ... */ void HandleOnTimer() { } /** * Handle Chart Event ... * * @param id: int, Event id ... * @param lparam: long, Event Long Parameter ... * @param dparam: double, Event Double Parameter ... * @param sparam: string, Event String Parameter ... */ void HandleOnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { } // // Validators ... /** * Validate Inputs ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // // TODO: Handle this ... result = true; // return result; } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnStopLossTriggered(const XDeal &deal) { // // Update Position Buttons ... UpdatePositionButtons(); // eaTarget.HandleOnStopLossTriggered(deal); // if (eaPositionDrawer != NULL) { eaPositionDrawer.HandleStopLossTriggered(deal); } } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnTakeProfitTriggered(const XDeal &deal) { // // Update Position Buttons ... UpdatePositionButtons(); // eaTarget.HandleOnTakeProfitTriggered(deal); // if (eaPositionDrawer != NULL) { eaPositionDrawer.HandleOnTakeProfitTriggered(deal); } } /** * 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 // ) { // // Update Position Buttons ... UpdatePositionButtons(); // eaTarget.HandleOnPositionForceClosed( ticket, position, comment // ); // if (eaPositionDrawer != NULL) { // eaPositionDrawer.HandleOnPositionForceClosed( ticket, position, comment // ); } } /** * Handle Position Partially Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void HandleOnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { } /** * Handle Deals Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnDealsChanged(int count) { } /** * Handle Orders Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnOrdersChanged(int count) { } /** * Handle Positions Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnPositionsChanged(int count) { // // Update Position Buttons ... UpdatePositionButtons(); } /** * 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 // ) { // if (eaPositionDrawer != NULL) { // eaPositionDrawer.HandleOnPositionModified( ticket, profit, comment // ); } } /** * Handle all Trades States Changed Event ... * * @param state: XOnTradeHandlerState instance refrence, Changed Trade State data ... */ void HandleOnTradeStateChanged(const XOnTradeHandlerState &state) { } /** * Handle New Signal Recieved ... * * @param signal: XSignal, reference to recieved Signal ... */ void HandleOnSignalTriggered(XSignal &signal) { // // Draw Signal ... XCSignalObject *iSignalObj = new XCSignalObject(); bool isCreated = iSignalObj.Create( eaChartHelper.ChartId(), 0, signal, 3 // ); if (isCreated) { } // // Handle Volume ... double iVolume = eaVolume.CalculateVolume(signal); if (!signal.ignoreEAVolume && iVolume != signal.volume) { signal.volume = iVolume; } // ENUM_X_SIGNAL_EXECUTION_RESULT result; bool isExcuted = eaTrader.ExecuteSignal( signal, result // ); if (isExcuted) { } } /** * Handle Signal Executed Event ... * * @param signal: XSignal, reference to Executed Signal ... */ void HandleOnSignalExecuted(XSignal &signal) { // eaTarget.AddExecutedSignal(signal); // if (eaPositionDrawer != NULL) { eaPositionDrawer.AddExecutedSignal(signal); } } // // Props and Setter / Getter (s) ... // // Trade Event Listeners ... // 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 // ); } // // Add New Signal Executed Event Handler ... void AddOnSignalExecutedEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalExecutedEventHandlers // ); } // // Protected ... protected: // // Private ... private: // // Props ... // // Trade Event Listeners ... TOnModify mOnModifyEventHandlers[]; TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; TOnSignal mOnSignalExecutedEventHandlers[]; TOnDealsChanged mDealsChangedEventHandlers[]; TOnOrdersChanged mOrdersChangedEventHandlers[]; TOnPartialClose mOnPartialCloseEventHandlers[]; TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; // // Object Props ... // string objSuffix; // CButton btnBuy; CButton btnSell; CButton btnClose; CButton btnCloseAll; CEdit lblPositionId; // CButton lblTP; CButton lblSL; CButton btnSLPlus; CButton btnTPPlus; CButton btnSLMinus; CButton btnTPMinus; CButton btnSLPlusPlus; CButton btnTPPlusPlus; CButton btnSLMinusMinus; CButton btnTPMinusMinus; // CArrayObj posArray; CButton *btnSelectedPosInfo; CArrayObj selectedPosInfoArr; // ulong selectedPositionID; bool showSelectedPositionInfo; // // GUI Event(s) ... /** * Initialize all GUI Requirements for EA ... * * @return ( bool ) */ bool InitGUI() { // bool result = false; // int subWindow = 0; ulong chartId = ChartID(); objSuffix = eaLogSuffix + "_"; // int startX = 5; int startY = 25; // int defaultGap = 5; int defaultWidth = 100; int defaultHeight = 30; // // Buy ... int btnBuyX1 = startX; int btnBuyX2 = startX + defaultWidth; int btnBuyY1 = startY; int btnBuyY2 = startY + defaultHeight; string btnBuyName = objSuffix + "BTN_BUY"; result = btnBuy.Create( chartId, btnBuyName, subWindow, btnBuyX1, btnBuyY1, btnBuyX2, btnBuyY2 // ); if (result) { // // Apply Buy Button Style ... // btnBuy.Text("Buy"); btnBuy.Color(clrYellow); btnBuy.ColorBackground(clrGreen); } // // Sell ... int btnSellX1 = btnBuyX1 + btnBuyX2; int btnSellX2 = btnSellX1 + defaultWidth; int btnSellY1 = btnBuyY1; int btnSellY2 = btnBuyY2; string btnSellName = objSuffix + "BTN_SELL"; result = btnSell.Create( chartId, btnSellName, subWindow, btnSellX1, btnSellY1, btnSellX2, btnSellY2 // ); if (result) { // // Apply Sell Button Style ... // btnSell.Text("Sell"); btnSell.Color(clrYellow); btnSell.ColorBackground(clrDarkRed); } // // LABEL Position ID ... int lblPositionIdX1 = btnBuyX1; int lblPositionIdX2 = lblPositionIdX1 + defaultWidth; int lblPositionIdY1 = btnSellY2 + defaultGap; int lblPositionIdY2 = lblPositionIdY1 + defaultHeight; string lblPositionIdName = objSuffix + "LBL_POS_ID"; result = lblPositionId.Create( chartId, lblPositionIdName, subWindow, lblPositionIdX1, lblPositionIdY1, lblPositionIdX2, lblPositionIdY2 // ); if (result) { // // Apply Label Position ID Style ... lblPositionId.ReadOnly(true); lblPositionId.Text("Pos ID: "); lblPositionId.Color(clrYellow); lblPositionId.ColorBackground(clrDarkGray); } // // Close ... int btnCloseX1 = startX; int btnCloseX2 = btnCloseX1 + defaultWidth; int btnCloseY1 = lblPositionIdY2 + defaultGap; int btnCloseY2 = btnCloseY1 + defaultHeight; string btnCloseName = objSuffix + "BTN_CLOSE"; result = btnClose.Create( chartId, btnCloseName, subWindow, btnCloseX1, btnCloseY1, btnCloseX2, btnCloseY2 // ); if (result) { // // Apply Close Button Style ... // btnClose.Text("Close"); btnClose.Color(clrYellow); btnClose.ColorBackground(clrDarkOrange); } // // Close All ... int btnCloseAllX1 = btnCloseX2 + defaultGap; int btnCloseAllX2 = btnCloseAllX1 + defaultWidth; int btnCloseAllY1 = lblPositionIdY2 + defaultGap; int btnCloseAllY2 = btnCloseAllY1 + defaultHeight; string btnCloseAllName = objSuffix + "BTN_CLOSE_ALL"; result = btnCloseAll.Create( chartId, btnCloseAllName, subWindow, btnCloseAllX1, btnCloseAllY1, btnCloseAllX2, btnCloseAllY2 // ); if (result) { // // Apply Close Button Style ... // btnCloseAll.Text("Close All"); btnCloseAll.Color(clrYellow); btnCloseAll.ColorBackground(clrDarkRed); } // int minusPlusWidth = 20; // // TP Label ... int lblTPX1 = btnCloseX1; int lblTPX2 = lblTPX1 + defaultWidth; int lblTPY1 = btnCloseY2 + defaultGap; int lblTPY2 = lblTPY1 + defaultHeight; string lblTPName = objSuffix + "LBL_TP"; result = lblTP.Create( chartId, lblTPName, subWindow, lblTPX1, lblTPY1, lblTPX2, lblTPY2 // ); if (result) { // // Apply Style ... lblTP.Disable(); lblTP.Text("TP"); lblTP.Color(clrWhite); lblTP.ColorBackground(clrGreen); } // // TP Plus ... int btnTPPlusX1 = lblTPX1; int btnTPPlusX2 = btnTPPlusX1 + minusPlusWidth; int btnTPPlusY1 = lblTPY2 + defaultGap; int btnTPPlusY2 = btnTPPlusY1 + defaultHeight; string btnTPPlusName = objSuffix + "BTN_TP_PLUS"; result = btnTPPlus.Create( chartId, btnTPPlusName, subWindow, btnTPPlusX1, btnTPPlusY1, btnTPPlusX2, btnTPPlusY2 // ); if (result) { // // Apply Style ... btnTPPlus.Text("+"); btnTPPlus.Color(clrYellow); btnTPPlus.ColorBackground(clrGreen); } // // TP Plus Plus ... int btnTPPlusPlusX1 = btnTPPlusX2 + defaultGap; int btnTPPlusPlusX2 = btnTPPlusPlusX1 + minusPlusWidth; int btnTPPlusPlusY1 = lblTPY2 + defaultGap; int btnTPPlusPlusY2 = btnTPPlusPlusY1 + defaultHeight; string btnTPPlusPlusName = objSuffix + "BTN_TP_PLUSPLUS"; result = btnTPPlusPlus.Create( chartId, btnTPPlusPlusName, subWindow, btnTPPlusPlusX1, btnTPPlusPlusY1, btnTPPlusPlusX2, btnTPPlusPlusY2 // ); if (result) { // // Apply Style ... btnTPPlusPlus.Text("++"); btnTPPlusPlus.Color(clrYellow); btnTPPlusPlus.ColorBackground(clrGreen); } // // TP Minus ... int btnTPMinusX1 = lblTPX2 - minusPlusWidth; int btnTPMinusX2 = btnTPMinusX1 + minusPlusWidth; int btnTPMinusY1 = lblTPY2 + defaultGap; int btnTPMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusName = objSuffix + "BTN_TP_MINUS"; result = btnTPMinus.Create( chartId, btnTPMinusName, subWindow, btnTPMinusX1, btnTPMinusY1, btnTPMinusX2, btnTPMinusY2 // ); if (result) { // // Apply Style ... btnTPMinus.Text("-"); btnTPMinus.Color(clrYellow); btnTPMinus.ColorBackground(clrDarkRed); } // // TP Minus Minus ... int btnTPMinusMinusX1 = btnTPMinusX1 - minusPlusWidth - defaultGap; int btnTPMinusMinusX2 = btnTPMinusMinusX1 + minusPlusWidth; int btnTPMinusMinusY1 = lblTPY2 + defaultGap; int btnTPMinusMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusMinusName = objSuffix + "BTN_TP_MINUSMINUS"; result = btnTPMinusMinus.Create( chartId, btnTPMinusMinusName, subWindow, btnTPMinusMinusX1, btnTPMinusMinusY1, btnTPMinusMinusX2, btnTPMinusMinusY2 // ); if (result) { // // Apply Style ... btnTPMinusMinus.Text("--"); btnTPMinusMinus.Color(clrYellow); btnTPMinusMinus.ColorBackground(clrDarkRed); } // // SL Label ... int lblSLX1 = btnCloseAllX1; int lblSLX2 = lblSLX1 + defaultWidth; int lblSLY1 = btnCloseAllY2 + defaultGap; int lblSLY2 = lblTPY1 + defaultHeight; string lblSLName = objSuffix + "LBL_SL"; result = lblSL.Create( chartId, lblSLName, subWindow, lblSLX1, lblSLY1, lblSLX2, lblSLY2 // ); if (result) { // // Apply Style ... lblSL.Disable(); lblSL.Text("SL"); lblSL.Color(clrWhite); lblSL.ColorBackground(clrDarkRed); } // // SL Plus ... int btnSLPlusX1 = lblSLX1; int btnSLPlusX2 = btnSLPlusX1 + minusPlusWidth; int btnSLPlusY1 = lblSLY2 + defaultGap; int btnSLPlusY2 = btnSLPlusY1 + defaultHeight; string btnSLPlusName = objSuffix + "BTN_SL_PLUS"; result = btnSLPlus.Create( chartId, btnSLPlusName, subWindow, btnSLPlusX1, btnSLPlusY1, btnSLPlusX2, btnSLPlusY2 // ); if (result) { // // Apply Style ... btnSLPlus.Text("+"); btnSLPlus.Color(clrYellow); btnSLPlus.ColorBackground(clrGreen); } // // SL Plus Plus ... int btnSLPlusPlusX1 = btnSLPlusX2 + defaultGap; int btnSLPlusPlusX2 = btnSLPlusPlusX1 + minusPlusWidth; int btnSLPlusPlusY1 = lblSLY2 + defaultGap; int btnSLPlusPlusY2 = btnSLPlusPlusY1 + defaultHeight; string btnSLPlusPlusName = objSuffix + "BTN_SL_PLUSPLUS"; result = btnSLPlusPlus.Create( chartId, btnSLPlusPlusName, subWindow, btnSLPlusPlusX1, btnSLPlusPlusY1, btnSLPlusPlusX2, btnSLPlusPlusY2 // ); if (result) { // // Apply Style ... btnSLPlusPlus.Text("++"); btnSLPlusPlus.Color(clrYellow); btnSLPlusPlus.ColorBackground(clrGreen); } // // SL Minus ... int btnSLMinusX1 = lblSLX2 - minusPlusWidth; int btnSLMinusX2 = btnSLMinusX1 + minusPlusWidth; int btnSLMinusY1 = lblSLY2 + defaultGap; int btnSLMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusName = objSuffix + "BTN_SL_MINUS"; result = btnSLMinus.Create( chartId, btnSLMinusName, subWindow, btnSLMinusX1, btnSLMinusY1, btnSLMinusX2, btnSLMinusY2 // ); if (result) { // // Apply Style ... btnSLMinus.Text("-"); btnSLMinus.Color(clrYellow); btnSLMinus.ColorBackground(clrDarkRed); } // // SL Minus Minus ... int btnSLMinusMinusX1 = btnSLMinusX1 - minusPlusWidth - defaultGap; int btnSLMinusMinusX2 = btnSLMinusMinusX1 + minusPlusWidth; int btnSLMinusMinusY1 = lblSLY2 + defaultGap; int btnSLMinusMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusMinusName = objSuffix + "BTN_SL_MINUSMINUS"; result = btnSLMinusMinus.Create( chartId, btnSLMinusMinusName, subWindow, btnSLMinusMinusX1, btnSLMinusMinusY1, btnSLMinusMinusX2, btnSLMinusMinusY2 // ); if (result) { // // Apply Style ... btnSLMinusMinus.Text("--"); btnSLMinusMinus.Color(clrYellow); btnSLMinusMinus.ColorBackground(clrDarkRed); } // UpdateGUIState(); // return result; } /** * Update GUI based on Each Ticks ... */ void UpdateGUI() { // UpdateGUIState(); // // Buy Button Pressed ... if (btnBuy.Pressed()) { // HandleBuyTrade(); btnBuy.Pressed(false); } // // Sell Button Pressed ... if (btnSell.Pressed()) { // HandleSellTrade(); btnSell.Pressed(false); } // // Close Button Pressed ... if (btnClose.Pressed()) { // if (btnClose.IsEnabled()) { // if (selectedPositionID > 0) { HandleCloseTrade(selectedPositionID); } } // btnClose.Pressed(false); } // // Close All Button Pressed ... if (btnCloseAll.Pressed()) { // if (btnCloseAll.IsEnabled()) { HandleCloseTrade(0); } // btnCloseAll.Pressed(false); } // // Check Show Hide Selected Position Info ... if (btnSelectedPosInfo != NULL) { // if (btnSelectedPosInfo.Pressed()) { // // Check Enable ... if (btnSelectedPosInfo.IsEnabled()) { // // Handle Toggle Show/Hide lblSelectedPositionInfo ... CEdit *iLbl = NULL; bool isVisible = showSelectedPositionInfo; int count = selectedPosInfoArr.Total(); if (IsValidSize(count)) { // // Loop Through Labels ... for (int i = 0; i < count; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); isVisible = iLbl.IsVisible(); if (isVisible) { iLbl.Hide(); } else { iLbl.Show(); } } // // Update Button Text ... isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); showSelectedPositionInfo = !showSelectedPositionInfo; } // ZeroMemory(iLbl); } // btnSelectedPosInfo.Pressed(false); } } // // TP Managing ... // // TP Plus ... if (btnTPPlus.Pressed()) { // if (btnTPPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH); } // btnTPPlus.Pressed(false); } // // TP Plus Plus ... if (btnTPPlusPlus.Pressed()) { // if (btnTPPlusPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH, 2); } // btnTPPlusPlus.Pressed(false); } // // TP Minus ... if (btnTPMinus.Pressed()) { // if (btnTPMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH); } // btnTPMinus.Pressed(false); } // // TP Minus Minus ... if (btnTPMinusMinus.Pressed()) { // if (btnTPMinusMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH, 2); } // btnTPMinusMinus.Pressed(false); } // // SL Managing ... // // SL Plus ... if (btnSLPlus.Pressed()) { // if (btnSLPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH); } // btnSLPlus.Pressed(false); } // // SL Plus Plus ... if (btnSLPlusPlus.Pressed()) { // if (btnSLPlusPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH, 2); } // btnSLPlusPlus.Pressed(false); } // // SL Minus ... if (btnSLMinus.Pressed()) { // if (btnSLMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH); } // btnSLMinus.Pressed(false); } // // SL Minus Minus ... if (btnSLMinusMinus.Pressed()) { // if (btnSLMinusMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH, 2); } // btnSLMinusMinus.Pressed(false); } // // Check Positions Buttons ... int posCount = posArray.Total(); bool has = IsValidSize(posCount); if (has) { // for (int i = 0; i < posCount; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // if (iBtn.Pressed()) { // if (iBtn.IsEnabled()) { // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); if (posID > 0 && selectedPositionID != posID) { selectedPositionID = posID; UpdateGUIState(); } } // iBtn.Pressed(false); } // ZeroMemory(iBtn); } } } /** * Destroy all Initialized GUi Requirements ... */ void DestroyGUI() { // delete eaChartHelper; ZeroMemory(eaChartHelper); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } /** * Update GUI Element Styles ... */ void UpdateGUIState() { // // Update States Of Position Select Buttons ... int count = posArray.Total(); bool has = IsValidSize(count) && selectedPositionID > 0; if (has) { // for (int i = 0; i < count; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); // // Select Position ... XPosition iPos; bool hasPosition = eaTrader.GetPosition( posID, iPos // ); string iTooltip = !hasPosition ? "" : IsLong(iPos.type) ? "Long" : "Short"; // if (posID == selectedPositionID) { // iBtn.Disable(); iBtn.ColorBackground(clrDarkGray); } else { // iBtn.Enable(); // color iBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; // iBtn.ColorBackground(iBtnBG); } // ZeroMemory(iBtn); } } // // Update State of Close All ... if (has && count > 1) { // btnCloseAll.Enable(); btnCloseAll.ColorBackground(clrDarkRed); } else { // btnCloseAll.Disable(); btnCloseAll.ColorBackground(clrDarkGray); } // // Update Selected Position Info Button State ... if (has) { // // Reading Global Chart Info ... int subWindow = 0; int chartWidth = eaChartHelper.Width(); ulong chartId = eaChartHelper.ChartId(); // // Read Selected Position ... XPosition selectedPosition; bool hasPosition = eaTrader.GetPosition( selectedPositionID, selectedPosition // ); // // Read All Positions ... double profits = 0; XPosition positions[]; string positionsInfo = ""; int positionsCount = eaTrader.GetPositions(positions); has = IsValidSize(positionsCount); if (has) { // for (int i = 0; i < positionsCount; i++) { profits += positions[i].profit; } // if (positionsCount > 1) { positionsInfo = "Positions Count: " + ToXString(positionsCount) + ", Profits: " + ToXString(profits); } } // if (hasPosition) { // // Preparing Position Info ... string posTicket = "Ticket: " + ToXString(selectedPosition.ticket); string posType = "Type: " + ToXString(selectedPosition.type); string posSymbolPeriod = "Symbol: " + selectedPosition.symbol + ", " + "Period: " + ToXString(selectedPosition.period); string posProfit = "Profit: " + ToXString(selectedPosition.profit); string posRiskToRewardRatio = "RiskToReward: " + ToXString(selectedPosition.GetRiskRewardRatio()); string accountInfo = "Balance: " + ToXString(eaTrader.mAccount.GetBalance()) + ", " + "Equity: " + ToXString(eaTrader.mAccount.GetEquity()); // string posInfos[]; // // Ticket ... Add( posTicket, posInfos // ); // // Type ... Add( posType, posInfos // ); // // Symbol Period ... Add( posSymbolPeriod, posInfos // ); // // Profit ... Add( posProfit, posInfos // ); // // Risk to Reward Ratio ... Add( posRiskToRewardRatio, posInfos // ); // // Add Positions Info if Exists ... if (IsSpecifiedValid(positionsInfo)) { // Add( positionsInfo, posInfos // ); // // Clear Info Array ... selectedPosInfoArr.Clear(); } // // Adding Account Info ... Add( accountInfo, posInfos // ); // // Create Button If Not Exists ... if (btnSelectedPosInfo == NULL) { // btnSelectedPosInfo = new CButton(); // string name = objSuffix + "BTN_TOOGLE_SPOS_INFO"; // CRect iRect = btnTPPlus.Rect(); // int x1 = iRect.left; int x2 = x1 + 200 + 5; // int y1 = iRect.bottom + 5; int y2 = y1 + iRect.Height(); // bool isCreated = btnSelectedPosInfo.Create( chartId, name, subWindow, x1, y1, x2, y2 // ); if (!isCreated) { // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } else { // // Apply Styles ... btnSelectedPosInfo.Color(clrYellow); btnSelectedPosInfo.ColorBackground(clrDarkBlue); } } // // Check Btn Exists ... has = btnSelectedPosInfo != NULL; if (has) { // int posInfoCount = ArraySize(posInfos); int lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount) && lblInfoCount == posInfoCount; // // Create info Labels ... if (!has) { // selectedPosInfoArr.Clear(); has = IsValidSize(posInfoCount); if (has) { // // Creat Info Control ... // string name = objSuffix + "LBL_SPOS_INFO"; // int lblHeight = 25; int lblWidth = 450; // int startX = chartWidth - lblWidth - 5; int sizeX = startX + lblWidth; // int startY = 5; int sizeY = startY + lblHeight; // // Loop through Position Info's Array to Create Label Controls ... for (int i = 0; i < posInfoCount; i++) { // string iText = posInfos[i]; string iTextMD5 = ToMD5(iText); // string iName = name + "_" + iTextMD5; // int iX1 = startX; int iX2 = sizeX; // int iY1 = startY; int iY2 = startY + lblHeight; // CEdit *iLbl = new CEdit(); bool isCreated = iLbl.Create( chartId, iName, subWindow, iX1, iY1, iX2, iY2 // ); if (isCreated) { // iLbl.Text(iText); iLbl.Color(clrYellow); iLbl.ColorBorder(clrDarkSlateGray); iLbl.ColorBackground(clrDarkSlateGray); // if (showSelectedPositionInfo) { iLbl.Show(); } else { iLbl.Hide(); } // selectedPosInfoArr.Add(iLbl); // startY = iY2; } } } } // // Update Info Labels ... lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount); if (has) { // CEdit *iLbl = NULL; // // Loop Through Infos ... for (int i = 0; i < lblInfoCount; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); // iLbl.Text(posInfos[i]); } // bool isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); // ZeroMemory(iLbl); } } // ZeroMemory(posInfos); } // SpecifiedClean(positions); } else { // // Toggle Selected Position Btn ... if (btnSelectedPosInfo != NULL) { // btnSelectedPosInfo.Destroy(); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } // // Selected Position Lbls ... selectedPosInfoArr.Clear(); } // // Update State of BtnClose and BtnClose All ... if (selectedPositionID == 0) { // btnClose.Disable(); btnClose.ColorBackground(clrDarkGray); // lblTP.Disable(); lblTP.ColorBackground(clrDarkGray); // btnTPPlus.Disable(); btnTPPlus.ColorBackground(clrDarkGray); // btnTPPlusPlus.Disable(); btnTPPlusPlus.ColorBackground(clrDarkGray); // btnTPMinus.Disable(); btnTPMinus.ColorBackground(clrDarkGray); // btnTPMinusMinus.Disable(); btnTPMinusMinus.ColorBackground(clrDarkGray); // lblSL.Disable(); lblSL.ColorBackground(clrDarkGray); // btnSLPlus.Disable(); btnSLPlus.ColorBackground(clrDarkGray); // btnSLPlusPlus.Disable(); btnSLPlusPlus.ColorBackground(clrDarkGray); // btnSLMinus.Disable(); btnSLMinus.ColorBackground(clrDarkGray); // btnSLMinusMinus.Disable(); btnSLMinusMinus.ColorBackground(clrDarkGray); } else { // btnClose.Enable(); btnClose.ColorBackground(clrDarkOrange); // lblTP.Enable(); lblTP.ColorBackground(clrGreen); // btnTPPlus.Enable(); btnTPPlus.ColorBackground(clrGreen); // btnTPPlusPlus.Enable(); btnTPPlusPlus.ColorBackground(clrGreen); // btnTPMinus.Enable(); btnTPMinus.ColorBackground(clrDarkRed); // btnTPMinusMinus.Enable(); btnTPMinusMinus.ColorBackground(clrDarkRed); // lblSL.Enable(); lblSL.ColorBackground(clrDarkRed); // btnSLPlus.Enable(); btnSLPlus.ColorBackground(clrGreen); // btnSLPlusPlus.Enable(); btnSLPlusPlus.ColorBackground(clrGreen); // btnSLMinus.Enable(); btnSLMinus.ColorBackground(clrDarkRed); // btnSLMinusMinus.Enable(); btnSLMinusMinus.ColorBackground(clrDarkRed); } } /** * Update Position's Selector Buttons ... */ void UpdatePositionButtons() { // // Retrieve Positions ... XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (!has) { // posArray.Clear(); selectedPositionID = 0; UpdateGUIState(); return; } // posArray.Clear(); // // Selected Position ID ... bool isSelectdPositionIDExists = false; if (has && selectedPositionID > 0) { // for (int i = 0; i < count; i++) { // if (!isSelectdPositionIDExists && positions[i].ticket == selectedPositionID) { // isSelectdPositionIDExists = true; break; } } } if (!isSelectdPositionIDExists || selectedPositionID == 0) { // XPosition youngest; int youngestIDX = GetXYoungest(youngest, positions); bool hasYoungest = IsValidIndex(youngestIDX) && youngest.IsValid(); if (hasYoungest) { selectedPositionID = youngest.ticket; } // youngest.Clean(); } // int subWindow = 0; ulong chartId = eaChartHelper.ChartId(); // int btnWidth = 25; int btnHeight = 25; // CRect iRect = lblPositionId.Rect(); // int lastX = iRect.left + iRect.Width() + 5; int lastSizeX = lastX + btnWidth; // int lastY = iRect.top; int lastSizeY = lastY + iRect.Height(); // for (int i = 0; i < count; i++) { // XPosition iPos = positions[i]; // string posTypeStr = IsLong(iPos.type) ? "LONG" : "SHORT"; // int iPosBtnX = lastX; int iPosBtnSizeX = iPosBtnX + btnWidth; string iPosBtnName = objSuffix + "_" + posTypeStr + "_POS_SELECT_BTN_" + ToXString(iPos.ticket); // CButton *iPosBtn = new CButton(); has = iPosBtn.Create( chartId, iPosBtnName, subWindow, iPosBtnX, lastY, iPosBtnSizeX, lastSizeY // ); if (has) { // // Apply Styles ... string iPosBtnText = ToXString(iPos.ticket); // iPosBtn.Text(iPosBtnText); iPosBtn.Color(clrWhite); // color iPosBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; iPosBtn.ColorBackground(iPosBtnBG); // lastX = iPosBtnSizeX + 5; // if (selectedPositionID == iPos.ticket) { iPosBtn.Disable(); } // posArray.Add(iPosBtn); } // iPos.Clean(); } // ZeroMemory(positions); UpdateGUIState(); } // // GUI Event Handlers ... // void HandleBuyTrade() { HandleTrade(X_DIRECTION_BULLISH); } // void HandleSellTrade() { HandleTrade(X_DIRECTION_BEARISH); } // void HandleTrade(ENUM_X_DIRECTION dir) { // if (!HasDirection(dir)) { return; } // NormalizeProps(); // bool isBullish = IsSpecifiedBullish(dir); // double r2r = riskToRewardRatio; double _volume = volume; double _riskInPoints = riskInPoint; double point = GetPoints(symbol); double entry = GetEntry(symbol, dir); // double risk = _riskInPoints * point; double reward = risk * r2r; // double sl = isBullish ? entry - risk : entry + risk; double tp = isBullish ? entry + reward : entry - reward; // string comment = eaLogSuffix + "_POS_" + ToXString(dir); // if (isBullish) { // eaTrader.Buy( symbol, period, _volume, entry, sl, tp, comment // ); } else { // eaTrader.Sell( symbol, period, _volume, entry, sl, tp, comment // ); } } // void HandleCloseTrade(ulong positionID) { // if (positionID == 0) { // XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (has) { // int closedCount = eaTrader.Close(positions); has = IsValidSize(closedCount); } } else { // XPosition position; bool has = eaTrader.GetPosition( positionID, position // ); if (has) { // has = eaTrader.Close(positionID); } } } // void HandleTPChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizeProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * allowedTPSLStep); // bool mustIncrease = isBullish ? isLong : !isLong; // double tp = position.tp; tp = mustIncrease ? tp + stepValue : tp - stepValue; bool isModified = eaTrader.Modify( position.ticket, position.sl, tp, objSuffix + "Change TP" // ); if (isModified) { UpdateGUIState(); } // position.Clean(); } // void HandleSLChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizeProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * allowedTPSLStep); // bool mustIncrease = isBullish ? !isLong : isLong; // double risk = position.GetRiskInPoint(); if (risk <= minAllowedRiskInPoint) { // position.Clean(); return; } // double sl = position.sl; sl = mustIncrease ? sl + stepValue : sl - stepValue; bool isModified = eaTrader.Modify( position.ticket, sl, position.tp, objSuffix + "Change SL" // ); if (isModified) { UpdateGUIState(); } // position.Clean(); } // // Custom Tools ... // void NormalizeProps() { // if (volume < 0.01) { volume = 0.01; } // if (riskInPoint < 0) { riskInPoint = 50; } // if (allowedTPSLStep < 5) { allowedTPSLStep = 5; } // if (riskToRewardRatio < 0.5) { riskToRewardRatio = 2; } // if (minAllowedRiskInPoint < 10) { minAllowedRiskInPoint = 10; } } // ulong ExtractPositionIDFromButtonName(string name) { // ulong result = 0; // string nameParts[]; int namePartsCount = SplitContent(nameParts, name, "_"); bool has = IsValidSize(namePartsCount); if (has) { // string lastPart = nameParts[namePartsCount - 1]; StringReplace(lastPart, "_", ""); result = (long)lastPart; } // ZeroMemory(nameParts); // return result; } }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-bar.analyser.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XPOI // Description: Bar Analysing ... // // 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 "../Libraries/x-saherelm.x-poi.lib.mq5" // // Definitions ... // // Extensions ... void FillLiquidity( XOHCL &lBar, ENUM_X_DIRECTION lDir, XBoxZone &lq, datetime to // ) { // // Normalize Args ... lq.Clean(); to = NormalizeTime(to); // // Validate Args ... bool has = lBar.IsValid() && HasDirection(lDir); if (!has) { return; } // lq.to = to; lq.dir = lDir; lq.type = "XLQ"; lq.from = lBar.time; lq.symbol = lBar.symbol; lq.period = lBar.period; lq.upper = IsBullish(lDir) ? lBar.GetDown() : lBar.high; lq.lower = IsBullish(lDir) ? lBar.low : lBar.GetUp(); } // // Implementations ... class XCBarAnalyser : public XCBase { // public: // // // Constructor(s) ... XCBarAnalyser() { } // // Deconstructor ... ~XCBarAnalyser() { } // // Getter(s) / Setter(s) ... // // Providers ... /** * Calculate Loopback Data for Specific Bar ... * * @param index: Integer, Bar Current Index ... * @param start: Integer, Start of Loopback ... * @param end: Integer, End of Loopback ... * @param count: Integer, Number of Calculating Bars ... * @param bar: XOHCL instance, Specified Bar ... * @param loopback: Integer, Loopback Length ... * @return ( bool ) */ bool CalculateLoopbackData( int &index, int &start, int &end, int &count, XOHCL &bar, int loopback = 1 // ) { // bool result = false; // if (loopback < 1) { loopback = 1; } // index = -1; start = -1; end = -1; count = -1; // result = bar.IsValid(); if (!result) { return result; } // index = bar.Index(); start = index + 1; end = start + loopback; count = end - start; result = count >= 1; if (!result) { return result; } // return result; } /** * Retrieve Loopback HH & LL Data ... * * @param hhIDX: Integer, HH Index ... * @param hh: Double, HH Value ... * @param llIDX: Integer, LL Index ... * @param ll: Double, LL Value ... * @param bar: XOHCL instance ... * @param loopback: Integer, Loopback Length ... * * @return ( bool ) */ bool CalculateLoopbackHLData( int &hhIDX, double &hh, int &llIDX, double &ll, XOHCL &bar, int loopback // ) { // bool result = false; // if (loopback < 1) { loopback = 1; } // int index = -1; int start = -1; int end = -1; int count = -1; result = CalculateLoopbackData( index, start, end, count, bar, loopback // ); if (!result) { return result; } // hhIDX = iHighest( bar.symbol, bar.period, MODE_HIGH, count, start // ); result = IsValidIndex(hhIDX); if (!result) { return result; } // llIDX = iLowest( bar.symbol, bar.period, MODE_LOW, count, start // ); result = IsValidIndex(llIDX); if (!result) { return result; } // hh = iHigh( bar.symbol, bar.period, hhIDX // ); ll = iLow( bar.symbol, bar.period, llIDX // ); // return result; } /** * Fill Prices ... * * @param prices: double collection * @param bar: XOHCL instance reference, Provides Start ... * @param loopback: int, Specified How Many Bars Process ... * @param type: ENUM_X_PRICE member, Specified Price Type ... * * @return ( bool ) */ int FillPrice( double &prices[], XOHCL &bar, int loopback = 14, ENUM_X_PRICE type = X_PRICE_CLOSE // ) { // int result = 0; // Clean(prices); // loopback = NormalizeInt(loopback, 1); // bool has = IsValid(type) && bar.IsValid(); if (!has) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // // Calculate Loopback Data ... int index = -1; int start = -1; int end = -1; int count = -1; has = CalculateLoopbackData( index, start, end, count, bar, loopback // ); if (!has) { return result; } // for (int i = start; i < end; i++) { // XOHCL iBar; bool isInited = iBar.Init( symbol, period, i // ); if (!isInited) { // iBar.Clean(); continue; } // double iPrice = iBar.GetPrice(type); // isInited = NotEmptyZero(iPrice); if (isInited) { // Add( iPrice, prices // ); } // iBar.Clean(); } // result = ArraySize(prices); has = result == count; if (!has) { // Clean(prices); } // ArrayReverse(prices); // return result; } /** * Calculate Price Range ... * * @param ranges: double Collection, Calculated Ranges ... * @param bar: XOHCL instance Reference, Start Bar ... * @param forceBody: bool, Force to Calculate Range using Body ... * @param forceDiff: bool, Force to Calculate Range using Onl Price Diff ... * @param loopback: int, loopback period for Range Calculations ... * * @return ( int ) */ int GetPriceRange( double &ranges[], XOHCL &bar, bool forceBody = false, bool forceDiff = false, int loopback = 14 // ) { // int result = 0; // Clean(ranges); // loopback = NormalizeInt(loopback, 1); // if (!bar.IsValid()) { return result; } // bool has = false; // // Select Uppers Prices ... double uppers[]; int uppersCount = 0; if (forceBody) { // has = FillPrice( uppers, bar, loopback, X_PRICE_UP // ); } else { // has = FillPrice( uppers, bar, loopback, X_PRICE_HIGH // ); } if (has) { uppersCount = ArraySize(uppers); } // // Select Lower Prices ... double lowers[]; int lowersCount = 0; if (forceBody) { // has = FillPrice( lowers, bar, loopback, X_PRICE_DOWN // ); } else { // has = FillPrice( lowers, bar, loopback, X_PRICE_LOW // ); } if (has) { lowersCount = ArraySize(lowers); } // // Validate Filled Prices ... has = IsValidSize(uppersCount) && IsValidSize(lowersCount) && uppersCount == lowersCount; if (!has) { // Clean(uppers); Clean(lowers); // return result; } // for (int i = 0; i < uppersCount; i++) { // double iDiff = uppers[i] - lowers[i]; double iValue = forceDiff ? iDiff : lowers[i] + iDiff; // Add( iValue, ranges // ); } // result = ArraySize(ranges); ArrayReverse(ranges); // // Cleanup Resources ... // Clean(uppers); Clean(lowers); // return result; } /** * Retrieve Price Velocities ... * * @param velocities: double Collection, Price Velocities ... * @param bar: XOHCL instance Reference, Start Bar ... * @param type: ENUM_X_PRICE member ... * @param loopback: int, loopback period for Calculations ... * * @return ( int ) */ int GetPriceVelocity( double &velocities[], XOHCL &bar, ENUM_X_PRICE type = X_PRICE_CLOSE, int loopback = 14 // ) { // int result = 0; // Clean(velocities); loopback = NormalizeInt(loopback, 1); // result = IsValid(type) && bar.IsValid(); // int to = bar.Index(); int from = to + loopback; for (int i = to; i < from; i++) { // double iPrice = GetAppliedPrice( bar.symbol, bar.period, i, type // ); // double pPrice = GetAppliedPrice( bar.symbol, bar.period, i + 1, type // ); // double iVelocity = MathAbs(iPrice - pPrice); Add( iVelocity, velocities // ); } // result = ArraySize(velocities); // return result; } /** * Calculate Price Change Percent ... * * @param bar: XOHCL instance Reference, Start Bar ... * @param type: ENUM_X_PRICE member, Specified Price Type ... * @param loopback: int, loopback period for Range Calculated ... * * @return ( double ) */ double GetPriceChangeRate( XOHCL &bar, ENUM_X_PRICE type = X_PRICE_MEDIAN, int loopback = 14 // ) { // double result = 0; // bool has = false; // loopback = NormalizeInt(loopback, 1); // has = bar.IsValid() && IsValid(type); if (!has) { return result; } // XOHCL oldBar; has = oldBar.Init( bar.symbol, bar.period, bar.Index() + loopback // ); if (!has) { // oldBar.Clean(); // return result; } double newPrice = bar.GetPrice(type); double oldPrice = oldBar.GetPrice(type); // result = ((newPrice - oldPrice) / oldPrice) / 100; // oldBar.Clean(); // return result; } /** * Detect Range Block ... */ bool DetectRangeBlocks( XOHCL &bar, XBoxZone &upper, XBoxZone &lower, int loopback = 288, ENUM_SERIESMODE upperRangeUpperMode = MODE_HIGH, ENUM_SERIESMODE upperRangeLowerMode = MODE_LOW, ENUM_SERIESMODE lowerRangeUpperMode = MODE_HIGH, ENUM_SERIESMODE lowerRangeLowerMode = MODE_LOW // ) { // bool result = false; // // Normalize Args ... upper.Clean(); lower.Clean(); loopback = NormalizeInt(loopback, 10); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // XOHCL iBar; result = iBar.Init( bar.symbol, bar.period, bar.Index() + loopback // ); if (!result) { // iBar.Clean(); // return result; } // double hhUpper = iBar.FindHighest(loopback, upperRangeUpperMode); double hhLower = iBar.FindHighest(loopback, upperRangeLowerMode); // double llUpper = iBar.FindLowest(loopback, lowerRangeUpperMode); double llLower = iBar.FindLowest(loopback, lowerRangeLowerMode); // double bhhUpper = bar.FindHighest(iBar.Index() - bar.Index(), upperRangeUpperMode); double bhhLower = bar.FindHighest(iBar.Index() - bar.Index(), upperRangeLowerMode); // double bllUpper = bar.FindLowest(iBar.Index() - bar.Index(), lowerRangeUpperMode); double bllLower = bar.FindLowest(iBar.Index() - bar.Index(), lowerRangeLowerMode); // hhUpper = MathMax(hhUpper, bhhUpper); hhLower = MathMax(hhLower, bhhLower); // llUpper = MathMin(llUpper, bllUpper); llLower = MathMin(llLower, bllLower); // datetime from = GetBarTime( iBar.symbol, iBar.period, iBar.Index() + loopback // ); // upper.from = from; upper.type = "XRNG"; upper.to = bar.time; upper.upper = hhUpper; upper.lower = hhLower; upper.symbol = iBar.symbol; upper.period = iBar.period; upper.dir = X_DIRECTION_BEARISH; // lower.from = from; lower.type = "XRNG"; lower.to = bar.time; lower.upper = llUpper; lower.lower = llLower; lower.symbol = iBar.symbol; lower.period = iBar.period; lower.dir = X_DIRECTION_BULLISH; // result = upper.IsValid() && lower.IsValid(); if (!result) { // iBar.Clean(); upper.Clean(); lower.Clean(); } // iBar.Clean(); // return result; } /** * Calculate Specified Bars Range Volume ... * * @param bar: XOHCL instance reference ... * @param bullishVolume: double * @param bearishVolume: double * @param loopback: int * * @return ( bool ) */ bool CalculateRangeVolume( XOHCL &bar, double &bullishVolume, double &bearishVolume, int loopback = 5 // ) { // bool result = false; // // Normalize Args ... bullishVolume = 0; bearishVolume = 0; loopback = NormalizeInt(loopback, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL iBar; bool has = false; int start = bar.Index(); int end = start + loopback; for (int i = start; i <= end; i++) { // iBar.Clean(); has = iBar.Init( bar.symbol, bar.period, i // ); if (!has) { // iBar.Clean(); // break; } // bool isBullish = iBar.IsBullish(); bool isBearish = iBar.IsBearish(); // if (isBullish) { bullishVolume += (double)iBar.volume; } else if (isBearish) { bearishVolume += (double)iBar.volume; } else { // bullishVolume += (double)iBar.volume; bearishVolume += (double)iBar.volume; } // iBar.Clean(); } // result = iBar.IsValid(); // iBar.Clean(); // return result; } /** * Detect Same Bars ... * * @param bar: XOHCL instance, Start Bar ... * @param dir: ENUM_X_DIRECTION member, Holds Result Direction ... * @param index: Integer, Holds Result Index ... * @param sameBars: Iteger, Required Same Bar ... * * @return ( bool ) */ bool HasSameBars( XOHCL &bar, ENUM_X_DIRECTION &dir, int &index, int sameBars = 3 // ) { // bool result = false; // dir = X_DIRECTION_NONE; // if (sameBars < 1) { sameBars = 1; } // result = bar.IsValid(); if (!result) { return result; } // index = bar.Index() + 1; bool canContinue = true; int sameBullishBarsFounded = 0; int sameBearishBarsFounded = 0; bool canContinueForBullish = true; bool canContinueForBearish = true; while (canContinue) { // XOHCL iBar; result = iBar.Init( bar.symbol, bar.period, index // ); if (!result) { break; } // bool isBullish = iBar.IsBullish(); bool isBearish = iBar.IsBearish(); result = isBullish || isBearish; if (!result) { break; } // if (isBullish) { // sameBullishBarsFounded++; canContinueForBearish = false; } else if (isBearish) { // sameBearishBarsFounded++; canContinueForBullish = false; } else { // sameBullishBarsFounded = 0; sameBearishBarsFounded = 0; canContinueForBullish = false; canContinueForBearish = false; } // result = canContinueForBullish || canContinueForBearish; if (!result) { break; } // canContinueForBullish = canContinueForBullish && sameBullishBarsFounded > 0; // canContinueForBearish = canContinueForBearish && sameBearishBarsFounded > 0; // canContinue = canContinueForBullish || canContinueForBearish; if (canContinue) { index++; } } // bool hasBullishSameBars = sameBullishBarsFounded >= sameBars; // bool hasBearishSameBars = sameBearishBarsFounded >= sameBars; // result = hasBullishSameBars || hasBearishSameBars; if (!result) { return result; } // index--; // dir = hasBullishSameBars ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } /** * Check Fibonacci Level 382 Pressure ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool HasFiboPressure( XOHCL &bar, ENUM_X_DIRECTION forDir, ENUM_X_FIBO_LEVELS level // ) { // bool result = false; // result = bar.IsValid() && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsBullish(forDir); bool isBearish = IsBearish(forDir); // double fiboLevelValue = GetFibonacciLevel( bar.high, bar.low, level, forDir // ); // bool isBullishPressured = isBullish && bar.GetDown() > fiboLevelValue; bool isBearishPressured = isBearish && bar.GetUp() < fiboLevelValue; // result = isBullishPressured || isBearishPressured; // return result; } /** * Detect Big Price Change Happens or not ... * * @param bar: XOHCL instance reference, Start Bar ... * @param dir: ENUM_X_DIRECTION member, Event Direction ... * @param rootIDX: int, Root of Momentum Index ... * @param type: ENUM_X_PRICE member, Price Type ... * @param forcBodyInRange: bool, Use Body in Range Detection ... * @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ... * * @return ( bool ) */ bool IsSharp( XOHCL &bar, ENUM_X_DIRECTION &dir, int &rootIDX, ENUM_X_PRICE type = X_PRICE_CLOSE, bool forcBodyInRange = true, double rangeExtendMultiplier = 2.0 // ) { // bool result = false; // dir = X_DIRECTION_NONE; rangeExtendMultiplier = NormalizeDouble(rangeExtendMultiplier, 1); // result = bar.IsValid() && IsValid(type); if (!result) { return result; } // double minPriceChangePercent = 0; int loopback = GetPeriodSharpData( minPriceChangePercent, bar.period // ); // // Retrieve Price Change Percent ... double priceChangePercent = GetPriceChangeRate( bar, type, loopback // ); // // Velocities ... double velocities[]; int velocitiesCount = GetPriceVelocity( velocities, bar, type, loopback // ); double velocitiesAvg = GetAverage(velocities); double oldPrice = GetAppliedPrice( bar.symbol, bar.period, bar.Index() + loopback, type // ); double newPrice = bar.GetPrice(type); double currVelocity = MathAbs(oldPrice - newPrice); // // Calculate HH and LL ... // double hh = 0; double ll = 0; int hhIDX = -1; int llIDX = -1; result = CalculateLoopbackHLData( hhIDX, hh, llIDX, ll, bar, loopback // ); result = result && ll > 0 && hh > ll && IsValidIndex(llIDX) && IsValidIndex(hhIDX); if (!result) { return result; } // int hhDiff = (hhIDX - bar.Index()); int llDiff = (llIDX - bar.Index()); // // Bool Get Boundary Direction ... // // Check Price Change Rate ... // bool isBullish = // hhDiff <= 1 && llIDX > hhIDX && priceChangePercent > 0 && priceChangePercent >= minPriceChangePercent && currVelocity > (velocitiesAvg * rangeExtendMultiplier) // ; // bool isBearish = // llDiff <= 1 && hhIDX > llIDX && priceChangePercent < 0 && MathAbs(priceChangePercent) >= minPriceChangePercent && currVelocity > (velocitiesAvg * rangeExtendMultiplier) // ; // result = isBullish || isBearish; if (result) { // rootIDX = isBullish ? llIDX : hhIDX; // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // return result; } // // Actions ... /** * Check a Bar is End of an OrderBlock Bar or Not ... * * @param bar: XOHCL ... * @param box: XBoxZone ... * @param forceFVGBarType: bool, Force all Bars must be Same as Direction ... * @param forceOBTwoBar: bool, Force Two Bars of OB Start must be InDirection ... * * @return ( bool ) */ bool IsOB( XOHCL &bar, XBoxZone &box, bool forceFVGBarType = false, bool forceOBTwoBar = false // ) { // bool result = false; // box.Clean(); // result = bar.IsValid(); if (!result) { return result; } // // Check Bar Must be FVG ... result = IsFVG( bar, box, forceFVGBarType // ); if (!result) { // box.Clean(); // return result; } // box.type = "XOB"; // bool isBullish = box.IsBullish(); bool isBearish = box.IsBearish(); // // Order Block Includes an FVG which Starts by atleast One // or More Indirectional Bars ... XOHCL fvgLastBar; XOHCL fvgLastBarPrev; XOHCL fvgLastBarPrev2; // int barIndex = bar.Index(); int fvgLastBarIndex = barIndex + 3; result = fvgLastBar.Init( bar.symbol, bar.period, fvgLastBarIndex // ); result = result && fvgLastBar.GetPreviousBar(fvgLastBarPrev); result = result && fvgLastBarPrev.GetPreviousBar(fvgLastBarPrev2); if (!result) { // box.Clean(); fvgLastBar.Clean(); fvgLastBarPrev.Clean(); fvgLastBarPrev2.Clean(); // return result; } // // Check FVG Last Bar ... // bool isBullishBlock = isBullish && (fvgLastBar.IsBearish() || (fvgLastBar.IsBullish() && fvgLastBarPrev.IsBearish())); // bool isBearishBlock = isBearish && (fvgLastBar.IsBullish() || (fvgLastBar.IsBearish() && fvgLastBarPrev.IsBullish())); // // Update Box ... // if (isBullishBlock || isBearishBlock) { // box.from = fvgLastBar.time; // box.lower = MathMin(box.lower, fvgLastBar.low); box.upper = MathMax(box.upper, fvgLastBar.high); } // // Apply Force Two Bar ... if (forceOBTwoBar) { // isBullishBlock = isBullishBlock && fvgLastBarPrev.IsBearish(); // isBearishBlock = isBearishBlock && fvgLastBarPrev.IsBullish(); // // Update Box ... if (isBullishBlock || isBearishBlock) { // box.from = fvgLastBarPrev.time; box.lower = MathMin(box.lower, fvgLastBarPrev.low); box.upper = MathMax(box.upper, fvgLastBarPrev.high); } } // result = isBullishBlock || isBearishBlock; if (!result) { // box.Clean(); fvgLastBar.Clean(); fvgLastBarPrev.Clean(); // return result; } // result = box.IsValid(); // // Cleanup Resources ... // fvgLastBar.Clean(); fvgLastBarPrev.Clean(); // return result; } /** * Check a Bar is End of an FVG Bar or Not ... * * @param bar: XOHCL ... * @param box: XBoxZone ... * @param forceType: bool, Force all Bars must be Same as Direction ... * * @return ( bool ) */ bool IsFVG( XOHCL &bar, XBoxZone &box, bool forceType = false // ) { // bool result = false; // box.Clean(); // result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; XOHCL p2Bar; result = bar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // bool isBullish = p2Bar.high < bar.low; bool isBearish = p2Bar.low > bar.high; // result = isBullish || isBearish; // // Apply Force Type ... if (result) { // if (isBullish) { // result = bar.IsBullish() && pBar.IsBullish() && p2Bar.IsBullish(); } else if (isBearish) { // result = bar.IsBearish() && pBar.IsBearish() && p2Bar.IsBearish(); } } // if (result) { // box.to = bar.time; box.from = p2Bar.time; box.symbol = bar.symbol; box.period = bar.period; box.dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; box.upper = isBullish ? bar.low : p2Bar.low; box.lower = isBullish ? p2Bar.high : bar.high; box.type = "XFVG"; } // pBar.Clean(); p2Bar.Clean(); // result = box.IsValid(); // return result; } /** * Check a Bar is a Trigger Box or Not ... * * @param bar: XOHCL instance Referernce, Specified Start Bar to Check ... * @param trigger: XBoxZone instance Reference, Holds Detected Trigger Bar ... * @param ob: XBoxZone instance Reference, Holds Detected Trigger Bar's OB ... * @param fvg: XBoxZone instance Reference, Holds Detected Trigger Bar's FVG ... * @param rLiquidity: XBoxZone instance Reference, Holds Detected Trigger Bar's Reversal Side Liquidity ... * @param fLiquidity: XBoxZone instance Reference, Holds Detected Trigger Bar's Following Side Liquidity ... * @param swingBar: XOHCL instance Referernce, Holds Detected Trigger Bar's Swing ... * @param loopback: int, Loopback Bars Count ... * @param maxAllowedRange: double, Max Allowed Trigger's OB Range ... * @param minAllowedBlockEdgeLength: int, Min Allowed Block Edge Validation Length ... * @param forceOBOppositBar: bool, Force OB to Start by Opposite Bar ... * @param forceFVGBarType: bool, Force FVG to Has Same Bar Type ... * @param forceGapBarBreakout: bool, Force Gap Bar Breakout OB Edge ... * @param forceHasSwingBar: bool, Force Has Swing Bar ... * @param forceHasLiquidity: bool, Force Has Following Liquidity ... * @param forceHasReversalLiquidity: bool, Force Has Reversal Liquidity ... * * @return ( bool ) */ bool IsTrigger( XOHCL &bar, XBoxZone &trigger, XBoxZone &ob, XBoxZone &fvg, XBoxZone &rLiquidity, XBoxZone &fLiquidity, XOHCL &swingBar, int loopback = 10, double maxAllowedRange = 0.0, int minAllowedBlockEdgeLength = 0, bool forceOBOppositBar = true, bool forceFVGBarType = true, bool forceGapBarBreakout = true, bool forceHasSwingBar = true, bool forceHasLiquidity = true, bool forceHasReversalLiquidity = true // ) { // bool result = false; // // Normalize Args ... ob.Clean(); fvg.Clean(); trigger.Clean(); swingBar.Clean(); rLiquidity.Clean(); fLiquidity.Clean(); loopback = NormalizeInt(loopback, 5); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; XOHCL tmpBar; XOHCL tmpPBar; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // result = bar.GetPreviousBar(pBar); // // Detect Base Order Block ... result = result && // // Order Block Detection ... IsOB( pBar, ob, forceFVGBarType, forceOBOppositBar // ) && // // Gap Detection ... IsFVG( pBar, fvg, forceFVGBarType // ); if (result) { // trigger = ob; trigger.type = "XTRG"; } // // Reading Requirements ... // double points = GetPoints(bar.symbol); // bool isBullish = ob.IsBullish(); bool isBearish = ob.IsBearish(); // int toIDX = trigger.ToIndex(); int fromIDX = trigger.FromIndex(); // // Validate Gaps Bar Breakeout ... if (result && forceGapBarBreakout) { // // Extract Gap Bar ... tmpBar.Clean(); tmpPBar.Clean(); result = // // Retrieve Bars ... fvg.ToBar(tmpBar) && tmpBar.GetPreviousBar(tmpPBar) && // // Validate Gap Bar is Momentum Bar ... IsMomentum( tmpPBar, iDir, 1 // ) && iDir == fvg.dir && // // Validate ... (isBullish ? tmpPBar.close > ob.upper : tmpPBar.close < ob.lower); // tmpBar.Clean(); tmpPBar.Clean(); } // // Validate Range ... if (result && maxAllowedRange > 0) { // double range = ob.GetRange(); result = range <= (maxAllowedRange * points); } // // Validating Swing Bar ... if (result && forceHasSwingBar) { // int swingIDX = -1; result = ob.FromBar(tmpBar); if (result) { // // Detect Swing Bar Index ... if (isBullish) { swingIDX = tmpBar.FindLowestIndex(loopback, MODE_LOW); } else if (isBearish) { swingIDX = tmpBar.FindHighestIndex(loopback, MODE_HIGH); } result = IsValidIndex(swingIDX); if (result) { // // Initialize Swing Bar ... result = swingBar.Init( bar.symbol, bar.period, swingIDX // ); } // // Update Trigger Block based on Swing Bar ... result = swingBar.IsValid(); if (result) { // // Update From ... trigger.from = ((datetime)MathMin((int)trigger.from, (int)swingBar.time)); // // Update Edge ... if (isBullish) { trigger.lower = MathMin(trigger.lower, swingBar.GetDown()); } else if (isBearish) { trigger.upper = MathMax(trigger.upper, swingBar.GetUp()); } } } // tmpBar.Clean(); } // // Validate Min Block Edge ... if (result && minAllowedBlockEdgeLength > 0) { // fromIDX = trigger.FromIndex(); if (result) { // // Looping Back ... for (int i = fromIDX; i < fromIDX + minAllowedBlockEdgeLength; i++) { // // Initialize i Bar ... result = tmpBar.Init( bar.symbol, bar.period, i // ); result = result && (isBullish ? tmpBar.low > trigger.lower : tmpBar.high > trigger.upper); if (!result) { break; } // tmpBar.Clean(); } result = tmpBar.IsValid(); // // Update Trigger Block ... if (result) { trigger.from = ((datetime)(MathMin((int)trigger.from, (int)tmpBar.time))); } } // tmpBar.Clean(); } // // Validating Liquidity ... if (result && (forceHasLiquidity || forceHasReversalLiquidity)) { // // Try to Detect Liquidity ... toIDX = ob.ToIndex(); for (int i = toIDX; i < toIDX + (loopback * 10); i++) { // // Initialize i Bar ... result = tmpBar.Init( bar.symbol, bar.period, i // ); if (!result) { break; } // // Detect Liquidity ... bool isRejected = result && IsRejected( tmpBar, iDir, false, // Force Bar Type ... true // Force Fibo Pressure ... ); bool isBullishRejected = isRejected && IsBullish(iDir); bool isBearishRejected = isRejected && IsBearish(iDir); // // Validate Liquidities ... if (isBullish) { // if (isBullishRejected && forceHasLiquidity && !fLiquidity.IsValid() && tmpBar.low < trigger.lower) { // // Filling Following Liquidity ... FillLiquidity( tmpBar, trigger.dir, fLiquidity, trigger.to // ); } // if (isBearishRejected && !rLiquidity.IsValid() && forceHasReversalLiquidity && tmpBar.high > trigger.upper) { // // Filling Revrsal Liquidity ... FillLiquidity( tmpBar, Opposit(trigger.dir), rLiquidity, trigger.to // ); } } else if (isBearish) { // if (isBearishRejected && forceHasLiquidity && !fLiquidity.IsValid() && tmpBar.high > trigger.upper) { // // Filling Following Liquidity ... FillLiquidity( tmpBar, trigger.dir, fLiquidity, trigger.to // ); } // if (isBullishRejected && !rLiquidity.IsValid() && forceHasReversalLiquidity && tmpBar.low < trigger.lower) { // // Filling Reversal Liquidity ... FillLiquidity( tmpBar, Opposit(trigger.dir), rLiquidity, trigger.to // ); } } // if ((!forceHasLiquidity ? true : fLiquidity.IsValid()) && (!forceHasReversalLiquidity ? true : rLiquidity.IsValid())) { break; } // tmpBar.Clean(); } tmpBar.Clean(); // result = (!forceHasLiquidity ? true : fLiquidity.IsValid()) && (!forceHasReversalLiquidity ? true : rLiquidity.IsValid()); } // // Cleanup Resources ... // pBar.Clean(); tmpBar.Clean(); tmpPBar.Clean(); // if (!result) { // ob.Clean(); fvg.Clean(); trigger.Clean(); swingBar.Clean(); rLiquidity.Clean(); fLiquidity.Clean(); // return result; } // return result; } // // Candlestick ... /** * Check Specified Bar is Doji Pattern or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param shadowMultiplier: double, Specified Shadow Multiplier ... * * @return ( bool ) */ bool IsDoji( XOHCL &bar, ENUM_X_DIRECTION &dir, double shadowMultiplier = 1.5 // ) { // bool result = false; // dir = X_DIRECTION_NONE; shadowMultiplier = NormalizeDouble(shadowMultiplier, 1.5, 3); // result = bar.IsValid(); if (!result) { return result; } // double body = bar.GetBody(); double range = bar.GetRange(); // result = body > 0 && range > 0 ? (body / range < 0.1) : false; if (result) { // dir = bar.GetLowShadow() >= (bar.GetHighShadow() * shadowMultiplier) ? X_DIRECTION_BULLISH : bar.GetHighShadow() >= (bar.GetLowShadow() * shadowMultiplier) ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; // result = HasDirection(dir); } // return result; } /** * Check Specified Bar is Swing or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ bool IsSwing( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 7 // ) { // bool result = false; // dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 1); // result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { // pBar.Clean(); ppBar.Clean(); return result; } // bool isBullish = // pBar.low < bar.low && pBar.low < ppBar.low && bar.GetDown() > pBar.low // ; // bool isBearish = // pBar.high > bar.high && pBar.high > ppBar.high && bar.GetUp() < pBar.high // ; // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // ppBar.Clean(); int pBarIDX = pBar.Index(); for (int i = pBarIDX + 1; i < pBarIDX + loopback; i++) { // bool has = ppBar.Init( pBar.symbol, pBar.period, i // ); // isBullish = has && isBullish && pBar.low < ppBar.low; // isBearish = has && isBearish && pBar.high > ppBar.high; } // result = isBullish || isBearish; if (!result) { dir = X_DIRECTION_NONE; } } // // Cleanup Resources ... // pBar.Clean(); ppBar.Clean(); // return result; } /** * Check Specified Bar's Prev Bar is Simple Swing or not ... * * @param bar: XOHCL instance reference, Specified Bar to it's Prev Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * * @return ( bool ) */ bool IsSimpleSwing( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // dir = X_DIRECTION_NONE; // // Valdate Args ... result = bar.IsValid(); // // Reading Requirements ... XOHCL cBar; XOHCL pBar; XOHCL p2Bar; result = bar.GetPreviousBar(cBar); result = result && cBar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); if (!result) { // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); // return result; } // // Now we Have to Check pBar is Swing Low or High ... // bool isPBarSwingLow = pBar.low < cBar.low && pBar.low < p2Bar.low; // bool isPBarSwingHigh = pBar.high > cBar.high && pBar.high > p2Bar.high; // result = isPBarSwingLow || isPBarSwingHigh; if (result) { // dir = isPBarSwingLow ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resourses ... // cBar.Clean(); pBar.Clean(); p2Bar.Clean(); // return result; } /** * Check Specified Bar is Hammer Pattern or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param bodyMultiplier: double, Specified Body Multiplier ... * * @return ( bool ) */ bool IsHammer( XOHCL &bar, ENUM_X_DIRECTION &dir, double bodyMultiplier = 2.0 // ) { // bool result = false; // dir = X_DIRECTION_NONE; bodyMultiplier = NormalizeDouble(bodyMultiplier, 1.5, 3); // result = bar.IsValid(); if (!result) { return result; } // double body = bar.GetBody(); double lShadow = bar.GetLowShadow(); double hShadow = bar.GetHighShadow(); // bool isBullish = hShadow < body && lShadow > (bodyMultiplier * body); // bool isBearish = lShadow < body && hShadow > (bodyMultiplier * body); // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // return result; } /** * Check Specified Bar is Engulfed Prev Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * * @return ( bool ) */ bool IsEngulfed( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // dir = X_DIRECTION_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // result = bar.GetBody() > pBar.GetBody(); if (!result) { // pBar.Clean(); return result; } // bool isBullish = bar.IsBullish() && pBar.IsBearish() && bar.GetDown() <= pBar.GetDown() && bar.GetUp() > pBar.GetUp(); // bool isBearish = bar.IsBearish() && pBar.IsBullish() && bar.GetUp() >= pBar.GetUp() && bar.GetDown() < pBar.GetDown(); // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resources ... // pBar.Clean(); // return result; } /** * Check Specified Bar is Momentum Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param forceBarType: bool, Force Apply Bar Type ... * @param forceFiboPressure: bool, Force Apply Bar Type ... * * @return ( bool ) */ bool IsRejected( XOHCL &bar, ENUM_X_DIRECTION &dir, bool forceBarType = true, bool forceFiboPressure = true // ) { // bool result = false; // dir = X_DIRECTION_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // bool isBullish = // bar.low < pBar.low && bar.GetShadows() > bar.GetBody() && bar.GetLowShadow() > bar.GetBody() && bar.GetLowShadow() > bar.GetHighShadow() // ; // bool isBearish = // bar.high > pBar.high && bar.GetShadows() > bar.GetBody() && bar.GetHighShadow() > bar.GetBody() && bar.GetHighShadow() > bar.GetLowShadow() // ; // result = isBullish || isBearish; if (!result) { // pBar.Clean(); return result; } // // Check Force Type ... if (forceBarType) { // isBullish = isBullish && bar.IsBullish(); // isBearish = isBearish && bar.IsBearish(); // result = isBullish || isBearish; if (!result) { // pBar.Clean(); return result; } } // // Check Force Fibo Pressure ... if (forceFiboPressure) { // bool hasBullishFiboPressure = HasFiboPressure( bar, X_DIRECTION_BULLISH, X_FIBO_LEVEL_236 // ); // bool hasBearishFiboPressure = HasFiboPressure( bar, X_DIRECTION_BEARISH, X_FIBO_LEVEL_236 // ); // isBullish = isBullish && hasBullishFiboPressure; // isBearish = isBearish && hasBearishFiboPressure; } // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // pBar.Clean(); // return result; } /** * Check Specified Bar is Momentum Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ bool IsMomentum( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 2 // ) { // bool result = false; // dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 1); // result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // // Calculate HH and LL ... double hh = 0; double ll = 0; int hhIDX = -1; int llIDX = -1; result = CalculateLoopbackHLData( hhIDX, hh, llIDX, ll, bar, loopback // s ); result = result && ll > 0 && hh > ll && IsValidIndex(llIDX) && IsValidIndex(hhIDX); if (!result) { // pBar.Clean(); return result; } // bool isBullish = bar.low > ll && bar.close >= hh && bar.IsBullish() && bar.low > pBar.low && bar.high > pBar.high && bar.GetBody() > pBar.GetBody() && bar.GetRange() > pBar.GetRange() && bar.GetShadows() < pBar.GetShadows(); // bool isBearish = bar.high < hh && bar.close <= ll && bar.IsBearish() && bar.low < pBar.low && bar.high < pBar.high && bar.GetBody() > pBar.GetBody() && bar.GetRange() > pBar.GetRange() && bar.GetShadows() < pBar.GetShadows(); // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // pBar.Clean(); // return result; } /** * Check Specified Bar is Pullback or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param loopback: int, Specified Loopback ... * @param forceBody: bool, Force Using Body ... * * @return ( bool ) */ bool IsPullback( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 3, bool forceBody = false // ) { // bool result = false; // dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // result = bar.IsValid(); if (!result) { return result; } // // Check Bar Must Engulfed ... result = IsEngulfed( bar, dir // ); if (!result) { return result; } // // Calculate HH and LL ... double hh = 0; double ll = 0; int hhIDX = -1; int llIDX = -1; result = CalculateLoopbackHLData( hhIDX, hh, llIDX, ll, bar, loopback // ); result = result && ll > 0 && hh > ll && IsValidIndex(llIDX) && IsValidIndex(hhIDX); if (!result) { return result; } // bool isBullish = bar.high > hh && bar.low > ll; // bool isBearish = bar.high < hh && bar.low < ll; // result = isBullish || isBearish; if (result) { // if (forceBody) { // isBullish = isBullish && bar.GetUp() > hh && bar.GetDown() > ll && llIDX == bar.Index() + 1; // isBearish = isBearish && bar.GetUp() < hh && bar.GetDown() < ll && hhIDX == bar.Index() + 1; // result = isBullish || isBearish; } // if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } } // return result; } /** * Check Specified Bar is Sequence Edge Breaker Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ bool IsSeqBreakEdge( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 3 // ) { // bool result = false; // // Normalize Args ... dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // bool isBullish = false; bool isBearish = false; // // Check Has Sequence or not ... XOHCL pBar; XOHCL iBar; XOHCL iPBar; bool has = false; int index = bar.Index(); int start = index + 1; int end = start + loopback - 1; bool hasBullishSeq = true; bool hasBearishSeq = true; for (int i = start; i < end; i++) { // // Initialize Indexed Bar(s) ... has = iBar.Init( bar.symbol, bar.period, i // ); has = has && iBar.GetPreviousBar(iPBar); // // Bullish Sequence ... if (hasBullishSeq) { // hasBullishSeq = has && iBar.low > iPBar.low; } // // Bearish Sequence ... if (hasBearishSeq) { // hasBearishSeq = has && iBar.high < iPBar.high; } // if (!hasBullishSeq && !hasBearishSeq) { break; } // iBar.Clean(); iPBar.Clean(); } iBar.Clean(); iPBar.Clean(); // // Check a Sequence Detect ... result = hasBullishSeq || hasBearishSeq; if (!result) { // pBar.Clean(); iBar.Clean(); iPBar.Clean(); // return result; } // // Retrieve Previous Bar ... result = bar.GetPreviousBar(pBar); // // Now we Have Ensure has a Sequence ... // isBullish = result && hasBearishSeq && bar.high > pBar.high; // isBearish = result && hasBullishSeq && bar.low < pBar.low; // // Summarizing Result ... result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resources ... pBar.Clean(); iBar.Clean(); iPBar.Clean(); // return result; } /** * Check Specified Bar is Sequence Type Breaker Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ bool IsSeqBreakType( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 3 // ) { // bool result = false; // // Normalize Args ... dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // bool isBullish = false; bool isBearish = false; // // Check Has Sequence or not ... XOHCL iBar; bool has = false; int index = bar.Index(); int start = index + 1; int end = start + loopback; bool hasBullishSeq = true; bool hasBearishSeq = true; for (int i = start; i < end; i++) { // // Initialize Indexed Bar(s) ... has = iBar.Init( bar.symbol, bar.period, i // ); // // Bullish Sequence ... if (hasBullishSeq) { // hasBullishSeq = has && iBar.IsBullish(); } // // Bearish Sequence ... if (hasBearishSeq) { // hasBearishSeq = has && iBar.IsBearish(); } // if (!hasBullishSeq && !hasBearishSeq) { break; } // iBar.Clean(); } iBar.Clean(); // // Check a Sequence Detect ... result = hasBullishSeq || hasBearishSeq; if (!result) { // iBar.Clean(); // return result; } // // Now we Have Ensure has a Sequence ... // isBullish = result && hasBearishSeq && bar.IsBullish(); // isBearish = result && hasBullishSeq && bar.IsBearish(); // // Summarizing Result ... result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resources ... iBar.Clean(); // return result; } /** * Check Specified Bar is Fully Sequence Breker Bar or not ... * * @param bar: XOHCL instance reference, Specified Bar to Check ... * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ bool IsSeqBreak( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 3 // ) { // bool result = false; // // Normalize Args ... dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // // Check Seq Edge ... ENUM_X_DIRECTION seqEdgeDir; bool isSeqEdgeBreaked = IsSeqBreakEdge( bar, seqEdgeDir // ); // // Check Seq Type ... ENUM_X_DIRECTION seqTypeDir; bool isSeqTypeBreaked = IsSeqBreakType( bar, seqTypeDir // ); // // Check Result ... result = isSeqEdgeBreaked && isSeqTypeBreaked && seqEdgeDir == seqTypeDir; if (result) { dir = seqEdgeDir; } // return result; } // // // /** * Check a Bar is Valid for Specified Direction of Positions ... * * @param bar: XOHCL instance, Start Bar ... * @param dir: ENUM_X_DIRECTION member, Provide Direction ... * * @return ( bool ) */ bool IsValidForTrigger( XOHCL &bar, ENUM_X_DIRECTION &dir, bool allowCond1 = true, bool allowCond2 = true, bool allowCond3 = true, bool allowCond4 = true, bool allowCond5 = true, bool allowCond6 = true, bool allowCond7 = true // ) { // bool result = false; // // Normalize Args ... dir = X_DIRECTION_NONE; // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // // Prepare Requirements ... XOHCL pBar; XOHCL p2Bar; int loopback = 3; bool isBullish = false; bool isBearish = false; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // // Retrieve Bar's Prev ... result = bar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); // // Handle Detect Trigger Bar ... if (result) { // // Check States ... // // Rejected ... bool isRejected = IsRejected( pBar, iDir, false, // Force Type ... true // Force Fibo Pressure ... ); bool isBullishRejected = isRejected && IsBullish(iDir); bool isBearishRejected = isRejected && IsBearish(iDir); // // Simple Rejected ... bool isSimpleRejected = IsRejected( pBar, iDir, false, // Force Type ... false // Force Fibo Pressure ... ); bool isSimpleBullishRejected = isSimpleRejected && IsBullish(iDir); bool isSimpleBearishRejected = isSimpleRejected && IsBearish(iDir); // // Full Directional Rejection ... bool isFullRejected = IsRejected( pBar, iDir, true, // Force Type ... true // Force Fibo Pressure ... ); bool isFullBullishRejected = isFullRejected && IsBullish(iDir); bool isFullBearishRejected = isRejected && IsBearish(iDir); // // Engulfed ... bool isEngulfed = IsEngulfed( pBar, iDir // ); bool isBullishEngulfed = isEngulfed && IsBullish(iDir); bool isBearishEngulfed = isEngulfed && IsBearish(iDir); // // Momentum ... bool isMomentum = IsMomentum( pBar, iDir // ); bool isBullishMomentum = isMomentum && IsBullish(iDir); bool isBearishMomentum = isMomentum && IsBearish(iDir); // // Simple Swing ... bool isSwing = IsSimpleSwing( pBar, iDir // ); bool isBullishSwing = isSwing && IsBullish(iDir); bool isBearishSwing = isSwing && IsBearish(iDir); // // Full Swing ... bool isFullSwing = IsSwing( pBar, iDir, 5 // ); bool isFullBullishSwing = isFullSwing && IsBullish(iDir); bool isFullBearishSwing = isFullSwing && IsBearish(iDir); // // Sequence Breaker ... bool isSeqBreak = IsSeqBreak( pBar, iDir, 3 // ); bool isBullishSeqBreak = isSeqBreak && IsBullish(iDir); bool isBearishSeqBreak = isSeqBreak && IsBearish(iDir); // // Now we have to Combine Conditions ... // // Cond 1 ... bool isBullishCond1 = false; bool isBearishCond1 = false; if (allowCond1) { // // Bullish ... isBullishCond1 = // isFullBullishRejected // ; // // Bearish ... isBearishCond1 = // isFullBearishRejected // ; } // // Cond 2 ... bool isBullishCond2 = false; bool isBearishCond2 = false; if (allowCond2) { // // Bullish ... isBullishCond2 = // isBullishSwing && isBullishRejected // ; // // Bearish ... isBearishCond2 = // isBearishSwing && isBearishRejected // ; } // // Cond 3 ... bool isBullishCond3 = false; bool isBearishCond3 = false; if (allowCond3) { // // Bullish ... isBullishCond3 = // isBullishSwing && (isBullishRejected || isBullishEngulfed || isBullishMomentum) // ; // // Bearish ... isBearishCond3 = // isBearishSwing && (isBearishRejected || isBearishEngulfed || isBearishMomentum) // ; } // // Cond 4 ... bool isBullishCond4 = false; bool isBearishCond4 = false; if (allowCond4) { // // Bullish ... isBullishCond4 = // isBullishSwing && isBullishSeqBreak && (isBullishRejected || isBullishEngulfed || isBullishMomentum) // ; // // Bearish ... isBearishCond4 = // isBearishSwing && isBearishSeqBreak && (isBearishRejected || isBearishEngulfed || isBearishMomentum) // ; } // // Cond 5 ... bool isBullishCond5 = false; bool isBearishCond5 = false; if (allowCond5) { // // Bullish ... isBullishCond5 = // isFullBullishSwing && (isBullishRejected || isBullishEngulfed || isBullishMomentum) // ; // // Bearish ... isBearishCond5 = // isFullBearishSwing && (isBearishRejected || isBearishEngulfed || isBearishMomentum) // ; } // // Cond 6 ... bool isBullishCond6 = false; bool isBearishCond6 = false; if (allowCond6) { // // Bullish ... isBullishCond6 = // p2Bar.IsBearish() && pBar.IsBullish() && pBar.low < p2Bar.low && pBar.high > p2Bar.high && pBar.GetDown() <= p2Bar.GetDown() && (isBullishEngulfed || isBullishMomentum || isSimpleBullishRejected) // ; // // Bearish ... isBearishCond6 = // p2Bar.IsBullish() && pBar.IsBearish() && pBar.high > p2Bar.high && pBar.low < p2Bar.low && pBar.GetUp() >= p2Bar.GetUp() && (isBearishEngulfed || isBearishMomentum || isSimpleBearishRejected) // ; } // // Cond 7 ... bool isBullishCond7 = false; bool isBearishCond7 = false; if (allowCond7) { // // Bullish ... isBullishCond7 = // p2Bar.IsBearish() && pBar.IsBullish() && pBar.low < p2Bar.low && pBar.high > p2Bar.high && pBar.GetUp() >= p2Bar.GetUp() // ; // // Bearish ... isBearishCond7 = // p2Bar.IsBullish() && pBar.IsBearish() && pBar.high > p2Bar.high && pBar.low < p2Bar.low && pBar.GetDown() <= p2Bar.GetDown() // ; } // // Summarizie Result ... // isBullish = // isBullishCond1 || isBullishCond2 || isBullishCond3 || isBullishCond4 || isBullishCond5 || isBullishCond6 || isBullishCond7 // ; // isBearish = // isBearishCond1 || isBearishCond2 || isBearishCond3 || isBearishCond4 || isBearishCond5 || isBearishCond6 || isBearishCond7 // ; } // // Summarize Result ... result = (isBullish && !isBearish) || (isBearish && !isBullish); if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resources ... pBar.Clean(); p2Bar.Clean(); // return result; } // protected: // // private: // // // Props ... // // Actions ... // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-chart.helper.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCChartHelper // Description: Chart Helper 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" // // Implementation ... class XCChartHelper : public XCBase { // // Public ... public: // // // Constructor ... XCChartHelper( ulong _chartId = 0, string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL) { // bool canSetSymbolPeriod = IsSpecifiedValid(_symbol) && IsSpecifiedValid(_period); // // Normalize ... if (!canSetSymbolPeriod) { // mChartID = NormalizeChartId(_chartId); mSymbol = NormalizeSymbol(_symbol); mPeriod = NormalizePeriod(_period); } else { // SetSymbolPeriod(mSymbol, mPeriod); } } // // Desconstructor ... ~XCChartHelper() { } // // Actioins ... /** * Redraw Specified Chart ... */ void Redraw() { ChartRedraw(mChartID); } /** * Chart Navigation ... * * @param position: ENUM_CHART_POSITION * @param shift: int * * @return ( bool ) */ bool Navigate( ENUM_CHART_POSITION position, int shift // ) { return (ChartNavigate(mChartID, position, shift)); } /** * Apply a Template to Chart ... * * @param filename: string file path ... * * @return ( bool ) */ bool ApplyTemplate(string filename) { return (ChartApplyTemplate(mChartID, filename)); } /** * Add Specified Indicator to Chart ... * * @param subWindow: int ... * @param handle: int ... * * @return ( bool ) */ bool IndicatorAdd(int subWindow, int handle) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartIndicatorAdd(mChartID, subWindow, handle)); } /** * Delete Specified Indicator from Chart ... * * @param subWindow: int ... * @param name: string ... * * @return ( bool ) */ bool IndicatorDelete(int subWindow, string name) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartIndicatorDelete(mChartID, subWindow, name)); } /** * Count all Charts Indicator ... * * @param subWindow: int ... * * @return ( int ) */ int IndicatorsTotal(int subWindow) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartIndicatorsTotal(mChartID, subWindow)); } /** * Get Specified Indexed Indicator's Name ... * * @param subWindow: int ... * @param index: int ... * * @return ( string ) */ string IndicatorName(int subWindow, int index) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartIndicatorName(mChartID, subWindow, index)); } /** * Set Chart Symbol, Period ... * * @param symbol: string ... * @param period: ENUM_TIMEFRAMES ... * * @return ( bool ) */ bool SetSymbolPeriod( string symbol, ENUM_TIMEFRAMES period // ) { bool result = (ChartSetSymbolPeriod(mChartID, symbol, period)); if (result) { // mSymbol = symbol; mPeriod = period; } // return result; } /** * Take an Screenshot of Chart ... * * @param filename: string file path ... * @param width: int ... * @param height: int ... * @param align_mode: ENUM_ALIGN_MODE ... * * @return ( bool ) */ bool ScreenShot( const string filename, const int width, const int height, const ENUM_ALIGN_MODE align_mode // ) const { return (ChartScreenShot(mChartID, filename, width, height, align_mode)); } /** * Writing parameters of chart to file ... **/ bool Save(const int file_handle) { // string work_str; int work_int; // bool has = false; // // Validate ... if (file_handle == INVALID_HANDLE || mChartID == -1) { return has; } // // Write start marker - 0xFFFFFFFFFFFFFFFF ... has = FileWriteLong(file_handle, -1) == sizeof(long); if (!has) { return has; } // // Write chart type ... has = FileWriteInteger(file_handle, Type(), INT_VALUE) == INT_VALUE; if (!has) { return has; } // // Write chart symbol ... work_str = Symbol(); work_int = StringLen(work_str); has = FileWriteInteger(file_handle, work_int, INT_VALUE) == INT_VALUE; if (!has) { return has; } if (work_int != 0) { // has = FileWriteString(file_handle, work_str, work_int) == work_int; if (!has) { return has; } } // // Write Period of chart ... has = FileWriteInteger(file_handle, Period(), INT_VALUE) == sizeof(int); if (!has) { return has; } // // Write value of the "Mode" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_MODE), INT_VALUE) == sizeof(int); if (!has) { return has; } // // Write value of the "Foreground" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_FOREGROUND), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "Shift" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShiftSize" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), INT_VALUE) == sizeof(int); if (!has) { return has; } // // Write value of the "AutoScroll" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_AUTOSCROLL), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "Scale" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE), INT_VALUE) == sizeof(int); if (!has) { return has; } // // Write value of the "ScaleFix" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ScaleFix_11" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX_11), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "FixedMax" property ... has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MAX)) == sizeof(double); if (!has) { return has; } // // Write value of the "FixedMin" property ... has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MIN)) == sizeof(double); if (!has) { return has; } // // Write the "ScalePPB" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE_PT_PER_BAR), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "PointsPerBar" property ... has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_POINTS_PER_BAR)) == sizeof(double); if (!has) { return has; } // // Write value of the "ShowOHLC" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OHLC), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowLineBid" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_BID_LINE), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowLineAsk" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_ASK_LINE), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowLastLine" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_LAST_LINE), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowPeriodSep" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_PERIOD_SEP), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowGrid" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_GRID), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // // Write value of the "ShowVolumes" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_VOLUMES), INT_VALUE) == sizeof(int); if (!has) { return has; } // // Write value of the "ShowObjectDescr" property ... has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OBJECT_DESCR), CHAR_VALUE) == sizeof(char); if (!has) { return has; } // return has; } /** * Load Specified Chart File ... * * @param file_handle: int ... * * @return ( bool ) */ bool Load(const int file_handle) { // string work_str; int work_int; // bool has = false; // // Validate ... if (file_handle == INVALID_HANDLE || mChartID == -1) { return has; } // // Read and checking start marker - 0xFFFFFFFFFFFFFFFF ... if (FileReadLong(file_handle) != -1) return has; // // Read and checking chart type ... if (FileReadInteger(file_handle, INT_VALUE) != Type()) return has; // // Read chart symbol ... work_int = FileReadInteger(file_handle); if (work_int != 0) { work_str = FileReadString(file_handle, work_int); } else { work_str = ""; } // // Read chart period ... work_int = FileReadInteger(file_handle); SetSymbolPeriod(work_str, (ENUM_TIMEFRAMES)work_int); // // Read value of the "Mode" property ... has = ChartSetInteger(mChartID, CHART_MODE, FileReadInteger(file_handle, INT_VALUE)); if (!has) { return has; } // // Read value of the "Foreground" property ... has = ChartSetInteger(mChartID, CHART_FOREGROUND, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Read value of the "Shift" property ... has = ChartSetInteger(mChartID, CHART_SHIFT, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Read value of the "ShiftSize" property ... has = ChartSetInteger(mChartID, CHART_SHIFT, FileReadInteger(file_handle, INT_VALUE)); if (!has) { return has; } // // Read value of the "AutoScroll" property ... has = ChartSetInteger(mChartID, CHART_AUTOSCROLL, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Read value of the "Scale" property ... has = ChartSetInteger(mChartID, CHART_SCALE, FileReadInteger(file_handle, INT_VALUE)); if (!has) { return has; } // // Read value of the "ScaleFix" property ... has = ChartSetInteger(mChartID, CHART_SCALEFIX, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Read value of the "ScaleFix_11" property ... has = ChartSetInteger(mChartID, CHART_SCALEFIX_11, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "FixedMax" property ... has = ChartSetDouble(mChartID, CHART_FIXED_MAX, FileReadDatetime(file_handle)); if (!has) { return has; } // // Rread value of the "FixedMin" property ... has = ChartSetDouble(mChartID, CHART_FIXED_MIN, FileReadDatetime(file_handle)); if (!has) { return has; } // // Rread value of the "ScalePPB" property ... has = ChartSetInteger(mChartID, CHART_SCALE_PT_PER_BAR, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "PointsPerBar" property ... has = ChartSetDouble(mChartID, CHART_POINTS_PER_BAR, FileReadDatetime(file_handle)); if (!has) { return has; } // // Rread value of the "ShowOHLC" property ... has = ChartSetInteger(mChartID, CHART_SHOW_OHLC, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowLineBid" property ... has = ChartSetInteger(mChartID, CHART_SHOW_BID_LINE, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowLineAsk" property ... has = ChartSetInteger(mChartID, CHART_SHOW_ASK_LINE, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowLastLine" property ... has = ChartSetInteger(mChartID, CHART_SHOW_LAST_LINE, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowPeriodSep" property ... has = ChartSetInteger(mChartID, CHART_SHOW_PERIOD_SEP, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowGrid" property ... has = ChartSetInteger(mChartID, CHART_SHOW_GRID, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // // Rread value of the "ShowVolumes" property ... has = ChartSetInteger(mChartID, CHART_SHOW_VOLUMES, FileReadInteger(file_handle, INT_VALUE)); if (!has) { return has; } // // Rread value of the "ShowObjectDescr" property ... has = ChartSetInteger(mChartID, CHART_SHOW_OBJECT_DESCR, FileReadInteger(file_handle, CHAR_VALUE)); if (!has) { return has; } // return has; } ulong Open() { // mChartID = ChartOpen(mSymbol, mPeriod); return (mChartID); } void Close() { // if (mChartID != -1 && mChartID != 0) { ChartClose(mChartID); mChartID = 0; } } // // Properties ... /** * Get Chart ID ... * * @return ( ulong ) */ ulong ChartId() { return mChartID; } /** * Get Object Type ... * * @return ( int ) **/ int Type() const { return (0x1111); } /** * Get Chart Mode ... * * @return ( ENUM_CHART_MODE ) **/ ENUM_CHART_MODE Mode() { return ((ENUM_CHART_MODE)ChartGetInteger(mChartID, CHART_MODE)); } /** * Get Chart Symbol ... * * @return ( string ) */ string Symbol() { return (ChartSymbol(mChartID)); } /** * Get Chart Period ... * * @return ( ENUM_TIMEFRAMES ) */ ENUM_TIMEFRAMES Period() { return (ChartPeriod(mChartID)); } /** * Count Chart Visible Bars ... * * @return ( int ) */ int VisibleBars() { return ((int)ChartGetInteger(mChartID, CHART_WIDTH_IN_BARS)); } /** * Get Chart First Visible Bars Index ... * * @return ( int ) */ int FirstVisibleBar() { return ((int)ChartGetInteger(mChartID, CHART_FIRST_VISIBLE_BAR)); } /** * Get Chart Last Visible Bars Index ... * * @return ( int ) */ int LastVisibleBar() { // int first = FirstVisibleBar(); int count = VisibleBars(); int result = first + count; return result; } /** * Get Chart's Specified SubWindows Minimum Price ... * * @param subWindow: int * @return ( double ) */ double PriceMin(int subWindow = 0) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartGetDouble(mChartID, CHART_PRICE_MIN, subWindow)); } /** * Get Chart's Specified SubWindows Maximum Price ... * * @param subWindow: int * @return ( double ) */ double PriceMax(int subWindow = 0) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (ChartGetDouble(mChartID, CHART_PRICE_MAX, subWindow)); } /** * Get Chart Width in Pixel ... * * @param subWindow: int ... * * @return ( int ) */ int Width(int subWindow = 0) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (int)ChartGetInteger(mChartID, CHART_WIDTH_IN_PIXELS, subWindow); } /** * Get Chart Height in Pixel ... * * @param subWindow: int ... * * @return ( int ) */ int Height(int subWindow = 0) { // // Normalize Subwindow ... if (subWindow <= 0) { subWindow = 0; } // return (int)ChartGetInteger(mChartID, CHART_HEIGHT_IN_PIXELS, subWindow); } // // Protected ... protected: // // Private ... private: // // Props ... // ulong mChartID; // Chart ID ... string mSymbol; // Chart Symbol ... ENUM_TIMEFRAMES mPeriod; // Chart Period ... }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-cobject.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XChartObjects // Description: provides all require Chart Objects ... // // // 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 // #include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5" // #include #include #include #include #include #include // // Definitions ... enum ENUM_XCHARTOBJECTS { // // Global ... X_EMPTY_OBJ = 7860, // Empty X_BOX_OBJ = 7861, // XBox X_BAR_ARROW_OBJ = 7862, // XBarArrow X_SIGNAL_OBJ = 8860, // XSignal X_OHCL_OBJ = 8863, // XBar X_RR_OBJ = 8864, // XRR X_POSITION_OBJ = 8865, // XPosition // // 9860 Custom Object ... }; enum ENUM_X_CHART_IDS { X_AT, // AT X_TO, // TO X_FROM, // FROM X_UPPER, // UPPER X_LOWER, // LOWER X_ENTRY, // ENTRY X_TARGET, // TARGET X_SL, // SL X_TP, // TP X_BAR_H_SHW, // HSHW X_BAR_BDY, // BODY X_BAR_L_SHW, // LSHW }; string ToString(ENUM_X_CHART_IDS value) { // string result = NULL; // result = EnumToString(value); // return result; } string ToXString(ENUM_XCHARTOBJECTS value) { // return EnumToString(value); } struct XPOIStyle { // // Properties ... int width; // Width ... color clr; // Color ... bool fill; // Fill, Use in Rectangles ... ENUM_LINE_STYLE style; // Line Style ... // // Constructor ... XPOIStyle() { Default(); } // // Tools ... // // Cleanup Model ... void Clean() { // width = 1; fill = false; clr = CLR_NONE; style = STYLE_SOLID; // ZeroMemory(this); } // // Default Props ... void Default() { // width = 1; fill = false; clr = CLR_NONE; style = STYLE_SOLID; } }; // // Extensions ... /** * Converts a XBoxZone struct to XSignal instance ... * * @param box: XBoxZone instance reference, provide source info ... * @param signal: XSignal instance reference, holds prepared converted signal ... * * @return ( bool ) */ bool ToXSignal( XBoxZone &box, XSignal &signal, double &rewardRatios[], double additionalSL = 0 // ) { // bool result = false; // signal.Clean(); // result = box.IsValid() && HasChild(rewardRatios); if (!result) { return result; } // XOHCL entryBar; int entryIDX = box.ToIndex(); if (entryIDX > 0) { entryIDX--; } result = entryBar.Init( box.symbol, box.period, entryIDX // ); if (!result) { // entryBar.Clean(); // return result; } // bool isBullish = box.IsBullish(); bool isBearish = box.IsBearish(); // ENUM_POSITION_TYPE iType = isBullish ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; ENUM_X_POSITION_TYPES iXType = isBullish ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; // double points = GetPoints(box.symbol); // double entry = isBullish ? box.upper : box.lower; entry = entryBar.open; // double sl = isBullish ? box.lower : box.upper; if (additionalSL > 0) { // sl = isBullish ? sl - additionalSL : sl + additionalSL; } // double risk = MathAbs(entry - sl); // double tp = 0; // // Calculate Target ... XTarget targets[]; // double tmp[]; int idx = -1; XTarget iTarget; bool has = false; double iRatio = 0; double iReward = 0; double iRewardPrice = 0; Copy( rewardRatios, tmp // ); while (HasChild(tmp)) { // idx = -1; iRatio = GetMaxWidthIndex( tmp, idx // ); // has = IsValidIndex(idx); if (!has) { break; } // has = iRatio > 0; // ArrayRemove( tmp, idx, 1 // ); // bool canSetTP = tp <= 0; // iReward = iRatio * risk; // iRewardPrice = isBullish ? entry + iReward : entry - iReward; if (canSetTP) { tp = iRewardPrice; } else { // iTarget.target = iRewardPrice; AddRef( iTarget, targets // ); // iTarget.Clean(); } } Clean(tmp); // // Filling Signal ... signal.tp = tp; signal.sl = sl; signal.type = iType; signal.comment = ""; signal.entry = entry; signal.time = box.to; signal.volume = 0.01; signal.provider = box.type; signal.symbol = box.symbol; signal.period = box.period; signal.mode = X_ORDER_MODE_MARKET; // if (HasChild(targets)) { // Copy( targets, signal.targets // ); } // result = signal.IsValid(); // // Cleanup Resources ... // if (!result) { signal.Clean(); } // Clean(tmp); Clean(targets); iTarget.Clean(); entryBar.Clean(); // return result; } /** * Converts a Signal to Position ... * * @param signal: XSignal, reference to Specified Signal ... * @param position: XPosition, reference to Generated Position ... * @param magic: ulong, Specified Magic Number ... * @param ticket: ulong, Specified Position Ticket ... * * @return ( bool ) */ bool ToXPosition( XSignal &signal, XPosition &position, ulong magic = 0, ulong ticket = 0 // ) { // bool result = false; // // Prepare ... position.Clean(); // // Validate ... result = signal.IsValid(); if (!result) { return result; } // // Normalize ... // if (ticket <= 0) { // if (signal.positionId > 0) { ticket = signal.positionId; } else { // ticket = MathRand(); signal.positionId = ticket; } } signal.positionId = ticket; // if (magic <= 0) { magic = MathRand(); } // // Filling Position ... position.swap = 0; position.profit = 0; position.magic = magic; position.commission = 0; position.tp = signal.tp; position.sl = signal.sl; position.ticket = ticket; position.type = signal.type; position.price = signal.entry; position.entry = signal.entry; position.openAt = signal.time; position.volume = signal.volume; position.symbol = signal.symbol; position.period = signal.period; position.comment = signal.comment; position.provider = signal.provider; // result = position.IsValid(); // // Cleanup Resources ... if (!result) { position.Clean(); } // return result; } /** * Update Specified Position by Bar ... * * @param position: XPosition, reference to Specified Position ... * @param barIndex: int, Specified Bar Index ... * * @return ( bool ) */ bool XUpdatePosition( XPosition &position, int barIndex = 0 // ) { // bool result = false; // // Normalize ... barIndex = NormalizeInt(barIndex, 0); // // Validate ... result = position.IsValid(); if (!result) { return result; } // XOHCL bar; result = bar.Init( position.symbol, position.period, barIndex // ); if (!result) { return result; } // double entryDiff = MathAbs(position.entry - position.price); bool isLong = IsLong(position.type); bool isInProfit = isLong ? position.price > position.entry : position.price < position.entry; bool isTargeted = isLong ? position.price >= position.tp : position.price <= position.tp; bool isStoped = isLong ? position.price <= position.sl : position.price >= position.sl; result = !isTargeted && !isStoped; if (!result) { return result; } // double spread = GetSpread(position.symbol); position.price = bar.close + (isLong ? spread : (-1 * spread)); entryDiff = MathAbs(position.entry - position.price); isInProfit = isLong ? position.price > position.entry : position.price < position.entry; result = position.IsValid(); // // Cleanup Resources ... bar.Clean(); // return result; } // // Implementation ... // // Global Chart Objects ... /** * Base Chart Object ... **/ class XCBaseObject : public CChartObject { // public: // // // Getter(s) / Setter(s) ... /** * Get Object Specified Name ... * * @return ( string ) */ string ObjName() { return mObjName; } /** * Set Object Specified Name ... * * @param value: String ... */ void ObjName(string value) { // Name(value); mObjName = value; } virtual string TypeString() { return ToXString(X_EMPTY_OBJ); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) const { return ((int)X_EMPTY_OBJ); } /** * Destroy ... */ void virtual Destroy() { // Detach(); Delete(); } // private: // // // Props ... string mObjName; // Object Specified Name ... // }; /** * Bar Arrow Object ... **/ class XCBarArrowObject : public XCBaseObject { // public: // /** * Creator ... * * @param chart_id: Long, Specified Chart ID ... * @param name: String, Specified Object ID ... * @param window: Integer, Specified Chart Window ID ... * @param swing: XCSwing instance ... * * @return ( bool ) */ bool CreateByBar( long chart_id, string name, int window, int arrow, XOHCL &bar, ENUM_X_PRICE priceType, double threshold = 5 // ) { // bool result = false; // result = // bar.IsValid() && IsValid(name) // ; if (!result) { return result; } // datetime time = bar.time; double price = bar.GetPrice(priceType); // if (threshold > 0) { // double thresholdPrice = threshold * GetPoints(bar.symbol); if (priceType == X_PRICE_HIGH) { price += thresholdPrice; } else if (priceType == X_PRICE_LOW) { price -= thresholdPrice; } } // result = mArrow.Create( chart_id, name, window, time, price, (char)arrow // ); // if (result) { ObjName(name); } // return result; } // // Virtual ... /** * Destroy ... */ void virtual Destroy() { // mArrow.Detach(); mArrow.Delete(); // Detach(); Delete(); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) { return (int)X_BAR_ARROW_OBJ; } /** * Type as String ... **/ string TypeString() override { return ToXString(X_BAR_ARROW_OBJ); } // // Setter(s) ... /** * Set Arrow Anchor ... * * @param value: ENUM_ARROW_ANCHOR member ... */ void ArrowAnchor(ENUM_ARROW_ANCHOR value) { mArrow.Anchor(value); } /** * Set Arrow Color ... * * @param value: Color ... */ void ArrowColor(color value) { mArrow.Color(value); } /** * Set Arrow Width ... * * @param value: Integer ... */ void ArrowWidth(int value) { mArrow.Width(value); } // private: // CChartObjectArrow mArrow; // }; /** * Signal Object ... **/ class XCSignalObject : public XCBaseObject { // public: // // // Constructor ... XCSignalObject() { } // // Deconstructor ... ~XCSignalObject() { } /** * Create a Signal Object on Chart ... * * @param chart_id: Long ... * @param name: String ... * @param window: Integer ... * @param signal: XSignal instance ... * @param length: int, Specified Length of Signal ... * * @return ( bool ) */ bool Create( long chart_id, const int window, XSignal &signal, int length = 3, string prefix = NULL // ) { // bool result = false; // length = NormalizeInt(length, 3); // result = signal.IsValid(); if (!result) { return result; } // string name = signal.GetTag(); if (IsValid(prefix)) { name = prefix + "_" + name; } string nameMD5 = ToMD5(name); // int delay = (PeriodSeconds(signal.period) * length); datetime time1 = (datetime)((int)signal.time - delay); datetime time2 = (datetime)((int)signal.time + delay); // // TP ... string tpName = ToString(X_TP) + "_" + nameMD5; result = mTPTrend.Create( chart_id, tpName, window, time1, signal.tp, time2, signal.tp // ); if (!result) { return result; } // // SL ... string slName = ToString(X_SL) + "_" + nameMD5; result = mSLTrend.Create( chart_id, slName, window, time1, signal.sl, time2, signal.sl // ); if (!result) { // mTPTrend.Delete(); return result; } // // TARGET ... bool hasTargets = HasChild(signal.targets); if (hasTargets) { // int targetsCount = ArraySize(signal.targets); for (int i = 0; i < targetsCount; i++) { // string targetName = ToString(X_TARGET) + "_" + ToXString(i) + "_" + nameMD5; CChartObjectTrend *mTargetTrend; mTargetTrend = new CChartObjectTrend(); result = mTargetTrend.Create( chart_id, targetName, window, time1, signal.targets[i].target, time2, signal.targets[i].target // ); if (!result) { // mTPTrend.Delete(); mSLTrend.Delete(); break; } // mTargetTrends.Add(mTargetTrend); } } // // ENTRY ... string entrName = ToString(X_ENTRY) + "_" + nameMD5; result = mEntryTrend.Create( chart_id, entrName, window, time1, signal.entry, time2, signal.entry // ); if (!result) { // mTPTrend.Delete(); mSLTrend.Delete(); mTargetTrends.Clear(); return result; } // // Set Object Name ... ObjName(name); // return result; } // // Virtual ... /** * Destroy ... */ void virtual Destroy() { // mTPTrend.Detach(); mTPTrend.Delete(); mSLTrend.Detach(); mSLTrend.Delete(); mEntryTrend.Detach(); mEntryTrend.Delete(); // mTargetTrends.Clear(); // Detach(); Delete(); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) { return (int)X_SIGNAL_OBJ; } /** * Type as String ... **/ string TypeString() override { return ToXString(X_SIGNAL_OBJ); } // // Setter(s) ... // // TP ... /** * Set TP Width ... * * @param value: Integer ... */ void TPWidth(int value) { // if (value < 1) { value = 1; } // mTPTrend.Width(value); } /** * Set TP Color ... * * @param value: Color ... */ void TPColor(color value) { mTPTrend.Color(value); } /** * Set TP Style ... * * @param value: ENUM_LINE_STYLE ... */ void TPStyle(ENUM_LINE_STYLE value) { mTPTrend.Style(value); } // // SL ... /** * Set SL Width ... * * @param value: Integer ... */ void SLWidth(int value) { // if (value < 1) { value = 1; } // mSLTrend.Width(value); } /** * Set SL Color ... * * @param value: Color ... */ void SLColor(color value) { mSLTrend.Color(value); } /** * Set SL Style ... * * @param value: ENUM_LINE_STYLE ... */ void SLStyle(ENUM_LINE_STYLE value) { mSLTrend.Style(value); } // // TARGET ... /** * Set Target Width ... * * @param value: Integer ... */ void TargetWidth(int value) { // if (value < 1) { value = 1; } // for (int i = 0; i < mTargetTrends.Total(); i++) { // CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); iTrend.Width(value); } } /** * Set Target Color ... * * @param value: Color ... */ void TargetColor(color value) { // for (int i = 0; i < mTargetTrends.Total(); i++) { // CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); iTrend.Color(value); } } /** * Set Target Style ... * * @param value: ENUM_LINE_STYLE ... */ void TargetStyle(ENUM_LINE_STYLE value) { // for (int i = 0; i < mTargetTrends.Total(); i++) { // CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); iTrend.Style(value); } } // // ENTRY ... /** * Set Entry Width ... * * @param value: Integer ... */ void EntryWidth(int value) { // if (value < 1) { value = 1; } // mEntryTrend.Width(value); } /** * Set Entry Color ... * * @param value: Color ... */ void EntryColor(color value) { mEntryTrend.Color(value); } /** * Set Entry Style ... * * @param value: ENUM_LINE_STYLE ... */ void EntryStyle(ENUM_LINE_STYLE value) { mEntryTrend.Style(value); } // private: // // CChartObjectTrend mTPTrend; CChartObjectTrend mSLTrend; CChartObjectTrend mEntryTrend; CArrayObj mTargetTrends; }; /** * XRR Object ... **/ class XCRRObject : public XCSignalObject { // // Public ... public: // // Constructor ... bool CreateBoxRR( long chart_id, const int window, XBoxZone &box, double &rewardRatios[], int length = 3, string prefix = NULL // ) { // bool result = false; // length = NormalizeInt(length, 3); // result = box.IsValid(); if (!result) { return result; } // XSignal signal; result = ToXSignal( box, signal, rewardRatios // ); if (!result) { // signal.Clean(); // return result; } // result = Create( chart_id, window, signal, length, prefix // ); // signal.Clean(); // return result; } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) { return (int)X_RR_OBJ; } /** * Type as String ... **/ string TypeString() override { return ToXString(X_RR_OBJ); } }; /** * XOHCL Object ... **/ class XCOHCLObject : public XCBaseObject { // public: // /** * Creator ... * * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param pivot: XPVPivot instance ... * @param prefix: String ... * * @return ( bool ) */ bool Create( long chart_id, int window, XOHCL &bar, datetime to, string prefix = NULL // ) { // bool result = false; // result = bar.IsValid() && IsValid(to); if (!result) { return result; } // string name = bar.GetTag(); if (IsValid(prefix)) { name = prefix + "_" + name; } string nameMD5 = ToMD5(name); // // High Shadow ... string hShadowName = ToString(X_BAR_H_SHW) + "_" + nameMD5; // result = mHighShadowRect.Create( chart_id, hShadowName, window, bar.time, bar.high, to, bar.GetUp() // ); if (!result) { return result; } // // Body ... string bodyName = ToString(X_BAR_BDY) + "_" + nameMD5; // result = mBodyRect.Create( chart_id, bodyName, window, bar.time, bar.GetUp(), to, bar.GetDown() // ); if (!result) { // mHighShadowRect.Delete(); mHighShadowRect.Detach(); return result; } // // Low Shadow ... string lShadowName = ToString(X_BAR_L_SHW) + "_" + nameMD5; // result = mLowShadowRect.Create( chart_id, lShadowName, window, bar.time, bar.GetDown(), to, bar.low // ); if (!result) { // mBodyRect.Delete(); mBodyRect.Detach(); mHighShadowRect.Delete(); mHighShadowRect.Detach(); return result; } // if (result) { ObjName(name); } // return result; } // // Virtual ... /** * Destroy ... */ void virtual Destroy() { // mBodyRect.Detach(); mBodyRect.Delete(); // mLowShadowRect.Detach(); mLowShadowRect.Delete(); // mHighShadowRect.Detach(); mHighShadowRect.Delete(); // Detach(); Delete(); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) { return (int)X_OHCL_OBJ; } /** * Type as String ... **/ string TypeString() override { return ToXString(X_OHCL_OBJ); } // // Getter(s) / Setter(s) ... /** * Set High Shadow Width ... * * @param value: Integer ... */ void HighShadowWidth(int value) { // if (value < 1) { value = 1; } // mHighShadowRect.Width(value); } /** * Set High Shadow Color ... * * @param value: Color ... */ void HighShadowColor(color value) { mHighShadowRect.Color(value); } /** * Set High Shadow Style ... * * @param value: ENUM_LINE_STYLE member ... */ void HighShadowStyle(ENUM_LINE_STYLE value) { mHighShadowRect.Style(value); } /** * Set High Shadow Fill ... * * @param value: Boolean ... */ void HighShadowFill(bool value) { mHighShadowRect.Fill(value); } /** * Set Body Width ... * * @param value: Integer ... */ void BodyWidth(int value) { // if (value < 1) { value = 1; } // mBodyRect.Width(value); } /** * Set Body Color ... * * @param value: Color ... */ void BodyColor(color value) { mBodyRect.Color(value); } /** * Set Body Style ... * * @param value: ENUM_LINE_STYLE member ... */ void BodyStyle(ENUM_LINE_STYLE value) { mBodyRect.Style(value); } /** * Set Body Fill ... * * @param value: Boolean ... */ void BodyFill(bool value) { mBodyRect.Fill(value); } /** * Set Low Shadow Width ... * * @param value: Integer ... */ void LowShadowWidth(int value) { // if (value < 1) { value = 1; } // mLowShadowRect.Width(value); } /** * Set Low Shadow Color ... * * @param value: Color ... */ void LowShadowColor(color value) { mLowShadowRect.Color(value); } /** * Set Low Shadow Style ... * * @param value: ENUM_LINE_STYLE member ... */ void LowShadowStyle(ENUM_LINE_STYLE value) { mLowShadowRect.Style(value); } /** * Set Low Shadow Fill ... * * @param value: Boolean ... */ void LowShadowFill(bool value) { mLowShadowRect.Fill(value); } void BarSpes( int width = 1, color clr = clrNONE, ENUM_LINE_STYLE style = STYLE_SOLID, bool fill = false // ) { // BodyWidth(width); LowShadowWidth(width); HighShadowWidth(width); // BodyColor(clr); LowShadowColor(clr); HighShadowColor(clr); // BodyStyle(style); LowShadowStyle(style); HighShadowStyle(style); // BodyFill(fill); LowShadowFill(fill); HighShadowFill(fill); } // private: // // // Props ... CChartObjectRectangle mHighShadowRect; CChartObjectRectangle mBodyRect; CChartObjectRectangle mLowShadowRect; }; /** * Box Object ... **/ class XCBoxObject : public XCBaseObject { // public: // /** * Creator ... * * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param pivot: XPVPivot instance ... * @param prefix: String ... * * @return ( bool ) */ bool Create( long chart_id, int window, string name, double upper, double lower, datetime from, datetime to, datetime at = NULL, string prefix = NULL // ) { // bool result = false; // result = upper > 0 && lower > 0 && to > from && IsValid(to) && IsValid(name) && IsValid(from) && upper > lower; if (!result) { return result; } // if (IsValid(prefix)) { name = prefix + "_" + name; } string nameMD5 = ToMD5(name); // result = mRect.Create( chart_id, name, window, from, upper, to, lower // ); if (!result) { return result; } // if (result) { // if (IsValid(at)) { // result = mAt.Create( chart_id, name + ToString(X_AT), window, at // ); } // if (!result) { // mAt.Detach(); mAt.Delete(); // mRect.Detach(); mRect.Delete(); } } // if (result) { ObjName(name); } // return result; } // // Virtual ... /** * Destroy ... */ void virtual Destroy() { // mAt.Detach(); mAt.Delete(); // mRect.Detach(); mRect.Delete(); // Detach(); Delete(); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual int Type(void) { return (int)X_BOX_OBJ; } /** * Type as String ... **/ string TypeString() override { return ToXString(X_BOX_OBJ); } // // Getter(s) / Setter(s) ... /** * Set Width ... * * @param value: Integer ... */ void BoxWidth(int value) { // if (value < 1) { value = 1; } // mAt.Width(value); mRect.Width(value); } /** * Set Color ... * * @param value: Color ... */ void BoxColor(color value) { // mAt.Color(value); mRect.Color(value); } /** * Set Style ... * * @param value: ENUM_LINE_STYLE member ... */ void BoxStyle(ENUM_LINE_STYLE value) { // mAt.Style(value); mRect.Style(value); } /** * Set Fill ... * * @param value: Boolean ... */ void BoxFill(bool value) { mRect.Fill(value); } // private: // // // Props ... CChartObjectVLine mAt; CChartObjectRectangle mRect; }; /** * Position Object ... **/ class XCPositionObject : public XCBaseObject { // // Public ... public: // XPOIStyle riskStyle; // Risk Box Style ... color inProfitColor; // In Profit Price Box Color ... color inDrawdownColor; // In Drawdown Price Box Color ... XPOIStyle rewardStyle; // Reward Box Style ... ENUM_LINE_STYLE priceStyle; // Price Box Style ... // // Creators ... /** * Create a Position Object by Signal reference ... * * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param signal: XSignal, reference to Provided Signal ... * @param magic: ulong, Specified Position Magic Number ... * @param ticket: ulong, Specified Position Ticket ... * * @return ( bool ) */ bool Create( long chart_id, int window, XSignal &signal, ulong magic = 0, ulong ticket = 0 // ) { // bool result = false; // // Converts Signal to Test Position ... XPosition _position; result = ToXPosition( signal, _position, magic, ticket // ); // // Validate ... result = chart_id >= 0 && window >= 0 && _position.IsValid(); if (!result) { return result; } // result = Create( chart_id, window, _position // ); // return result; } /** * Create a Position Object ... * * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param position: XPosition, reference to Specified Position ... * * @return ( bool ) */ bool Create( long chart_id, int window, XPosition &position // ) { // bool result = false; // // Validate ... result = chart_id >= 0 && window >= 0 && position.IsValid(); if (!result) { return result; } // result = Update(position); if (!result) { // Destroy(); return result; } // return result; } /** * Update Position if Belongs to ... * * @param position: XPosition, reference to Specified Position ... * @param barIndex: int, Specified Bar Index ... * * @return ( bool ) */ bool Update( XPosition &position, int barIndex = 0 // ) { // bool result = false; // // Normalize ... barIndex = NormalizeInt(barIndex, 0); // // Validate ... result = mChartID >= 0 && mWindowID >= 0 && position.IsValid() && (!HasPosition() ? true : IsBelong(position)); if (!result) { return result; } // datetime _toTime = GetBarTime( position.symbol, position.period, barIndex // ); // // Validate Chart Info ... result = UpdatePosition( position, _toTime // ); // return result; } /** * Update Position if Belongs to ... * * @param barIndex: int, Specified Bar Index ... * * @return ( bool ) */ bool Update(int barIndex = 0) { // bool result = false; // // Normalize ... barIndex = NormalizeInt(barIndex, 0); // // Validate ... result = HasPosition(); if (!result) { return result; } // // Update mPosition ... result = XUpdatePosition(mPosition, barIndex); if (!result) { return result; } // result = Update( mPosition, barIndex // ); // 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 ... /** * Check Object is Belongs to Specified Position or not ... * * @param position: XPosition, reference to Specified Position ... * * @return ( bool ) */ bool IsBelong(XPosition &position) { // bool result = false; // // Validate ... result = HasPosition() && position.IsValid(); // // Check ... result = result && mPosition.ticket == position.ticket; // return result; } // // Overrides ... /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ string TypeString() override { return ToXString(X_POSITION_OBJ); } /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ int Type(void) const override { return ((int)X_POSITION_OBJ); } /** * Destroy Object ... **/ void Destroy() override { // ObjName(NULL); // mRiskBox.Clean(); mPosition.Clean(); mPriceBox.Clean(); mRewardBox.Clean(); // mRiskBoxObj.Detach(); mRiskBoxObj.Delete(); // mPriceBoxObj.Detach(); mPriceBoxObj.Delete(); // mRewardBoxObj.Detach(); mRewardBoxObj.Delete(); } // // Stylers ... /** * Apply Styles based on Current Style Configurations ... */ void ApplyStyle() { // // Validate ... bool has = HasPosition(); if (!has) { return; } // // Check Position in Profit ... bool isLong = IsLong(mPosition.type); bool isRiskFreed = isLong ? mPosition.sl > mPosition.entry : mPosition.sl < mPosition.entry; bool isInProfit = mPosition.profit > 0; XPOIStyle _priceStyle; if (isInProfit) { // _priceStyle = rewardStyle; _priceStyle.clr = inProfitColor; } else { // _priceStyle = riskStyle; _priceStyle.clr = inDrawdownColor; } // // Apply Profit Based Styles ... _priceStyle.fill = true; _priceStyle.style = priceStyle; // // Change Risk Style if Risk Freed Position ... if (isRiskFreed) { // riskStyle.fill = true; riskStyle.clr = rewardStyle.clr; } // // Risk Style ... mRiskBoxObj.BoxColor(riskStyle.clr); mRiskBoxObj.BoxFill(riskStyle.fill); mRiskBoxObj.BoxStyle(riskStyle.style); mRiskBoxObj.BoxWidth(riskStyle.width); // // Reward Style ... mRewardBoxObj.BoxColor(rewardStyle.clr); mRewardBoxObj.BoxFill(rewardStyle.fill); mRewardBoxObj.BoxStyle(rewardStyle.style); mRewardBoxObj.BoxWidth(rewardStyle.width); // // Price Style .. mPriceBoxObj.BoxColor(_priceStyle.clr); mPriceBoxObj.BoxFill(_priceStyle.fill); mPriceBoxObj.BoxStyle(_priceStyle.style); mPriceBoxObj.BoxWidth(_priceStyle.width); // // Cleanup Resources ... _priceStyle.Clean(); } // void ApplyStyle( XPOIStyle &bullishStyle, XPOIStyle &bearishStyle // ) { // // Validate ... if (!HasPosition()) { return; } // // Risk Box ... if (mRiskBox.IsValid()) { // mRiskBoxObj.BoxColor(bearishStyle.clr); mRiskBoxObj.BoxFill(bearishStyle.fill); mRiskBoxObj.BoxStyle(bearishStyle.style); mRiskBoxObj.BoxWidth(bearishStyle.width); } // // Reward Box ... if (mRewardBox.IsValid()) { // mRewardBoxObj.BoxColor(bullishStyle.clr); mRewardBoxObj.BoxFill(bullishStyle.fill); mRewardBoxObj.BoxStyle(bullishStyle.style); mRewardBoxObj.BoxWidth(bullishStyle.width); } // // Price Box ... if (mPriceBox.IsValid()) { // XPOIStyle _priceStyle; if (mPriceBox.IsBullish()) { _priceStyle = bullishStyle; } else { _priceStyle = bearishStyle; } // mPriceBoxObj.BoxColor(_priceStyle.clr); mPriceBoxObj.BoxFill(_priceStyle.fill); mPriceBoxObj.BoxStyle(_priceStyle.style); mPriceBoxObj.BoxWidth(_priceStyle.width); // _priceStyle.Clean(); } } // // Protected ... protected: // // bool HasPosition() { return mPosition.IsValid(); } // bool UpdatePosition( XPosition &_position, datetime _toTime = NULL // ) { // bool result = false; // // Normalize ... _toTime = NormalizeTime(_toTime); // // Validate ... result = _position.IsValid() && (!HasPosition() ? true : _position.ticket == mPosition.ticket // ); if (!result) { return result; } // mPosition = _position; result = UpdateZones(_toTime); // return result; } // bool UpdateZones(datetime _toTime = NULL) { // bool result = false; // // Normalize ... _toTime = NormalizeTime(_toTime); // // Validate ... result = HasPosition(); if (!result) { return result; } // string iSymbol = mPosition.symbol; ENUM_TIMEFRAMES iPeriod = mPosition.period; // datetime iAt = mPosition.openAt; datetime iFrom = mPosition.openAt; // datetime _defaultToTime = iFrom + (PeriodSeconds(iPeriod) * 3); datetime iTo = _toTime <= _defaultToTime ? _defaultToTime : _toTime; // double iTP = mPosition.tp; double iSL = mPosition.sl; double iEntry = mPosition.entry; double iPrice = mPosition.price; // bool isLong = IsLong(mPosition.type); ENUM_X_DIRECTION iRiskDir = isLong ? X_DIRECTION_BEARISH : X_DIRECTION_BULLISH; ENUM_X_DIRECTION iRewardDir = isLong ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // bool isInProfit = mPosition.profit > 0; bool isRiskFreed = isLong ? mPosition.sl > mPosition.entry : mPosition.sl < mPosition.entry; ENUM_X_DIRECTION iPriceDir = isInProfit ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // Try to Update Zones ... string iSuffix = ToXString(mPosition.type) + "_" + ToXString(mPosition.ticket); string iPrefix = ToXString(TimeToSeconds(mPosition.openAt)); string iName = iSuffix + "_" + iPrefix; string iRiskName = iSuffix + "_" + "RISK" + "_" + iPrefix; string iPriceName = iSuffix + "_" + "PRICE" + "_" + iPrefix; string iRewardName = iSuffix + "_" + "REWARD" + "_" + iPrefix; // // Risk Box ... mRiskBox.to = iTo; mRiskBox.at = iAt; mRiskBox.lower = isLong ? isRiskFreed ? iEntry : iSL : isRiskFreed ? iSL : iEntry; mRiskBox.upper = isLong ? isRiskFreed ? iSL : iEntry : isRiskFreed ? iEntry : iSL; mRiskBox.from = iFrom; mRiskBox.symbol = iSymbol; mRiskBox.period = iPeriod; mRiskBox.type = iRiskName; mRiskBox.dir = isRiskFreed ? X_DIRECTION_BEARISH : X_DIRECTION_BULLISH; // // Reward Box ... mRewardBox.to = iTo; mRewardBox.at = iAt; mRewardBox.lower = isLong ? iEntry : iTP; mRewardBox.upper = isLong ? iTP : iEntry; mRewardBox.from = iFrom; mRewardBox.symbol = iSymbol; mRewardBox.period = iPeriod; mRewardBox.type = iRewardName; mRewardBox.dir = X_DIRECTION_BULLISH; // // Price Box ... mPriceBox.to = iTo; mPriceBox.at = iAt; mPriceBox.lower = isLong ? isInProfit ? isRiskFreed ? iSL : iEntry : iPrice : isInProfit ? isRiskFreed ? iSL : iPrice : iEntry; mPriceBox.upper = isLong ? isInProfit ? iPrice : iEntry : isInProfit ? iEntry : iPrice; mPriceBox.from = iFrom; mPriceBox.symbol = iSymbol; mPriceBox.period = iPeriod; mPriceBox.type = iPriceName; mPriceBox.dir = isInProfit ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // result = mRiskBox.IsValid() && mPriceBox.IsValid() && mRewardBox.IsValid(); if (!result) { return result; } // mRiskBoxObj.Detach(); mRiskBoxObj.Delete(); bool isRiskCreated = mRiskBoxObj.Create( mChartID, mWindowID, mRiskBox.type, mRiskBox.upper, mRiskBox.lower, mRiskBox.from, mRiskBox.to, NULL, // At ... NULL // Prefix ... ); // mRewardBoxObj.Detach(); mRewardBoxObj.Delete(); bool isRewardCreated = mRewardBoxObj.Create( mChartID, mWindowID, mRewardBox.type, mRewardBox.upper, mRewardBox.lower, mRewardBox.from, mRewardBox.to, NULL, // At ... NULL // Prefix ... ); // mPriceBoxObj.Detach(); mPriceBoxObj.Delete(); bool isPriceCreated = mPriceBoxObj.Create( mChartID, mWindowID, mPriceBox.type, mPriceBox.upper, mPriceBox.lower, mPriceBox.from, mPriceBox.to, NULL, // At ... NULL // Prefix ... ); // result = isRiskCreated && isPriceCreated && isRewardCreated; if (result) { // ObjName(iName); // // Apply Styles ... ApplyStyle(); } // return result; } // // Private ... private: // // Props ... // int mWindowID; long mChartID; // XBoxZone mRiskBox; XBoxZone mPriceBox; XPosition mPosition; XBoxZone mRewardBox; // XCBoxObject mRiskBoxObj; XCBoxObject mPriceBoxObj; XCBoxObject mRewardBoxObj; // }; // // Extensions ... /** * Add all Items of Specified CArrayObj into another ... * * @param source: CArrayObj, pointer refrence Specified Data Source ... * @param dest: CArrayObj, pointer refrence Specified Destination of Adding ... */ void AddObjects( CArrayObj *&source, CArrayObj &dest // ) { // bool has = source != NULL && source.Total() > 0; if (!has) { return; } // for (int i = 0; i < source.Total(); i++) { dest.Add(source.At(i)); } } /** * Remove Drawn Objects from Chart ... * * @param tag: Specified Object Name, if NULL remove all Objects ... * @param chartId: long, Specified Chart ... * @param subWindow: int Specified Sub Window ... */ void RemoveObjects( string tag = NULL, long chartId = -1, int subWindow = -1 // ) { // // Normalize Args ... // if (chartId == -1) { chartId = 0; } // if (subWindow == -1) { subWindow = 0; } // bool has = false; string iName = NULL; for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) { // // Retrieve Object Name ... iName = ObjectName(chartId, iObj, subWindow); // // Check Can Delete Object or not ... has = !IsSpecifiedValid(tag) ? true : StringFind(iName, tag) >= 0; if (has) { ObjectDelete(chartId, iName); } } // // Redraw Chart ... ChartRedraw(); } // // Color Manipulation Functions ... /** * Apply Alph to Color ... * * @param _clr: Specified Color ... * @param _alpha: Specified Alpha to Apply ... * * @return ( color ) */ color ApplyAlpha( color _clr, uchar _alpha = 255 // ) { // color result = _clr; // // Normalize ... _alpha = (uchar)NormalizeInt(_alpha, 0, 255); // uchar alpha = _alpha / 255; // uint uintColor = ColorToARGB(_clr, alpha); result = (color)uintColor; // return result; } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-data.collector.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: XCDataCollector ... // Description: Class for Handling Data Read or Write ... // // // 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 Handling Data Read or Write" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" // // Definitions ... // // Implementation ... class XCDataCollector : public XCBase { // // Public ... public: // // Constructors ... XCDataCollector() { mPath = "XDataCollector"; } // // Deconstructor ... ~XCDataCollector() { } // // Properties ... // string Path() { return mPath; } // void Path(string value) { mPath = value; } // // Tools ... // string GetFilePath(string fileName) { // string result = ""; // result = // (IsValid(mPath) ? 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; } // int GetFileHandlerForRead(string filePath) { // int result = INVALID_HANDLE; // if (!IsValid(filePath)) { return result; } // result = FileOpen( filePath, FILE_READ | FILE_TXT | FILE_ANSI // ); // 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(fileName) && 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(fileName) && 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; } /** * Read Specified File Content ... * * @param fileName: string, file name ... * @param content: string reference, hold's reading content ... * * @return ( bool ) */ bool Read( string fileName, string &content // ) { // bool result = false; // // Normalize Args ... content = NULL; // // Validate Args ... result = IsValid(fileName); if (!result) { return result; } // int mHandler = GetFileHandlerForRead(fileName); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // // Reading File ... while (!FileIsEnding(mHandler)) { // string iLine = FileReadString(mHandler); content += iLine; } // // Close File ... FileClose(mHandler); // return result; } /** * Read Specified File Content ... * * @param fileName: string, file name ... * @param content: string reference collection, hold's reading content lines ... * * @return ( bool ) */ bool Read( string fileName, string &content[] // ) { // bool result = false; // // Normalize Args ... Clean(content); // // Validate Args ... result = IsValid(fileName); if (!result) { return result; } // int mHandler = GetFileHandlerForRead(fileName); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // // Reading File ... while (!FileIsEnding(mHandler)) { // string iLine = FileReadString(mHandler); Add( iLine, content // ); } // // Close File ... FileClose(mHandler); // return result; } /** * Check Specified File Exists or not ... * * @param fileName: string, Full Path of File to Check ... * * @return ( bool ) */ bool IsExists(string fileName) { // bool result = false; // // Validate Args ... result = IsValid(fileName); if (!result) { return result; } // // Check File Exists or not ... int mHandler = GetFileHandlerForRead(fileName); result = mHandler != INVALID_HANDLE; FileClose(mHandler); // return result; } // // Protected ... protected: // // Private ... private: // // Props ... // string mPath; // Base Collector Path ... }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-expert.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCBaseExpret ... // Description: Base Expert Class ... // // // 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 Base Expert Class" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #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-signaller.class.mq5" #include "../Classes/x-saherelm.x-target.class.mq5" #include "../Classes/x-saherelm.x-trade-manager.class.mq5" #include "../Classes/x-saherelm.x-volume.class.mq5" // // Import Chart Objects ... #include #include #include #include // // Definitions ... // // Implementation ... class XCBaseExpert : public XCBase { // // Public ... public: // // Props ... // // Common ... long eaMagicNumber; // Magic Number int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix // // Symbol Configurations ... string eaSymbolConfiguration; // Symbol Configurations ... // // Management ... bool eaAllowGuards; // Allow Guards bool eaAllowTrade; // Allow Trade on Signals bool eaAllowLongs; // Allow Long Trades bool eaAllowShorts; // Allow Short Trades double eaMaxAllowedDrawdownFactor; // Max Allowed DrawDown for Trade // // Volume ... ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type double eaStaticVoluem; // Static Volume double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume double eaDynamicVolumeStepVolume; // Step of Volume Increasing double eaConstantRiskBalance; // Constant Risk Balance per Trade double eaConstantPercent; // Constant Percent of Balance Per Trade double eaConstantBalance; // Constant Balance for Calculations // // Alert ... bool eaEnableAlerts; // Enable Alerts bool eaSaveAlerts; // Save Alerts bool eaLogAlerts; // Log Alerts bool eaMailAlerts; // Mail Alerts bool eaPushAlerts; // Push Alerts bool eaTerminalAlerts; // Terminal Alerts // // Reports ... bool eaReportNewMonths; // Report New Month bool eaReportNewWeeks; // Report New Weeks bool eaReportNewDays; // Report New Days bool eaReportNewHours; // Report New Hours bool eaReportTrades; // Report Trades bool eaReportSignals; // Report Signals bool eaReportProtector; // Report Protector Actions bool eaReportRestrictions; // Report Restrictions bool eaReportAfterTradesBalance; // Report Balance after a Trade Finished // // Collector ... bool eaSaveTrades; // Save Trades bool eaSaveSignals; // Save Signals bool eaSaveWins; // Save Winning Conditions bool eaSaveLosts; // Save Lost Conditions bool eaSaveRestrictions; // Save Restriction Reports // // GUI Management Panel ... bool eaShowPanel; // Show Management Panel double eaPanelAllowedTPSLStep; // Value for Change TP/SL in Each Step double eaPanelMinAllowedRiskInPoint; // Min Allowed Risk in Point double eaPanelRiskInPoint; // Risk in Point per Trades double eaPanelRiskToRewardRatio; // Risk To Reward per Trades double eaPanelVolume; // Default volume Per Trade // // Requirements ... // XCAlert *eaAlert; // EA Scope Alert Handler ... XCGuard *eaGuard; // EA Scope Guard Handler ... XCTrade *eaTrader; // EA Scope Trade Handler ... XCVolume *eaVolume; // EA Scope Voluem Handler ... XCTarget *eaTarget; // EA Scope Target Handler ... XTimeTracker eaTimeTracker; // EA Scope Time Tracker ... XCTradeManager *eaTradeManager; // EA Scope Trade Manager Handler ... XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ... // // Specified Event Handlers ... TOnGuarded onGuardedEventHandler; TCanAnalyse canAnalyseEventHandler; TCheckForGuard checkForGuardEventHandler; // // Tools / Actions / Handlers ... // // Expert Advisor Event Handlers ... /** * Handle Initialization of Expert ... * * @return ( bool ) */ bool HandleOnInit() { // bool result = false; // // Validate Inputs ... result = ValidateInputs(); if (!result) { return result; } // int count = 0; bool has = false; // // Initialize Alert Handler ... eaAlert = new XCAlert(); eaAlert.SetPrefix(eaLogSuffix); eaAlert.SetLogAlerts(eaLogAlerts); eaAlert.SetMailAlerts(eaMailAlerts); eaAlert.SetPushAlerts(eaPushAlerts); eaAlert.SetSaveAlerts(eaSaveAlerts); eaAlert.SetEnableAlerts(eaEnableAlerts); eaAlert.SetTerminalAlerts(eaTerminalAlerts); // // Initialize Volume Manager ... eaVolume = new XCVolume(); result = eaVolume.Init( eaVolumeSelect, eaStaticVoluem, eaDynamicVolumeStepBalance, eaDynamicVolumeStepVolume, eaConstantRiskBalance, eaConstantPercent, eaConstantBalance // ); if (!result) { return result; } // // Initialize Trader ... eaTrader = new XCTrade( eaSlippage, eaMagicNumber, 0, 0, eaMaxAllowedDrawdownFactor // ); // // Trade Handler Attachments ... // // Position Modifiy Event Handlers ... count = ArraySize(mOnModifyEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]); } } // // Position Stop Loss Event Handlers ... count = ArraySize(mStopLossEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnStopLossEventHandler(mStopLossEventHandlers[i]); } } // // Position Take Profit Event Handlers ... count = ArraySize(mTakeProfitEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]); } } // // Position Force Close Event Handlers ... count = ArraySize(mOnForceCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]); } } // // Deals Changed Event Handlers ... count = ArraySize(mDealsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]); } } // // Orders Changed Event Handlers ... count = ArraySize(mOrdersChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]); } } // // Positions Changed Event Handlers ... count = ArraySize(mPositionsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]); } } // // Trade Changed Event Handlers ... count = ArraySize(mTradeStateChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]); } } // // Postion Partially Close Event Handlers ... count = ArraySize(mOnPartialCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]); } } // // Signal Executed Event Handlers ... count = ArraySize(mOnSignalExecutedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnSignalExecutedEventHandler(mOnSignalExecutedEventHandlers[i]); } } // // Initialize Guard Handler ... eaGuard = new XCGuard( eaAlert, eaTrader // ); // // Attach Event Handler ... eaGuard.onGuardEventListener = onGuardedEventHandler; // // Initialize Target Handler ... eaTarget = new XCTarget(eaTrader, eaAlert); // // Init Position Drawer ... eaPositionDrawer = new XCPositionDrawer(eaTrader); // // Initialize Trae Manager ... eaTradeManager = new XCTradeManager( eaAlert, eaTrader, eaVolume, eaGuard, eaTarget // ); // // Configuring Trade Manager ... // // Attache Check For Guard Event Listener ... eaTradeManager.checkForGuardEventListener = checkForGuardEventHandler; // eaTradeManager.SaveWins(eaSaveWins); eaTradeManager.SaveLosts(eaSaveLosts); eaTradeManager.SaveTrades(eaSaveTrades); eaTradeManager.SaveSignals(eaSaveSignals); eaTradeManager.SaveRestrictions(eaSaveRestrictions); // // Setting Trade Reports ... eaTradeManager .SetTradeReports( eaReportTrades, eaReportSignals, eaReportProtector, eaReportRestrictions, eaReportAfterTradesBalance // ); // // Setting Trade Permissions ... eaTradeManager .SetTradePermissions( eaAllowTrade, eaAllowLongs, eaAllowShorts // ); // // Setting Symbol Configuration ... XSymbolTradeConfig symbolConfigurations[]; eaTradeManager.SetSymbolConfigurations(eaSymbolConfiguration); count = eaTradeManager.FillSymbolConfigurations(symbolConfigurations); has = IsValidSize(count); if (has) { // // Configure Signallers ... for (int i = 0; i < count; i++) { // // Register Signallers ... PrepareSignallers(symbolConfigurations[i]); } } SpecifiedClean(symbolConfigurations); // result = InitPanel(); if (!result) { return result; } // return result; } /** * Handle De Initialization of Expert ... */ void HandleOnDeInit() { // DestroyPanel(); // delete eaTrader; ZeroMemory(eaTrader); // delete eaGuard; ZeroMemory(eaGuard); // delete eaVolume; ZeroMemory(eaVolume); // eaTarget.Destroy(); delete eaTarget; ZeroMemory(eaTarget); // delete eaTradeManager; ZeroMemory(eaTradeManager); // eaPositionDrawer.Destroy(); delete eaPositionDrawer; ZeroMemory(eaPositionDrawer); // eaTimeTracker.Clean(); // SpecifiedClean(eaSignallers); SpecifiedClean(mOnSignalEventHandlers); SpecifiedClean(mOnModifyEventHandlers); SpecifiedClean(mStopLossEventHandlers); SpecifiedClean(mTakeProfitEventHandlers); SpecifiedClean(mOnForceCloseEventHandlers); SpecifiedClean(mDealsChangedEventHandlers); SpecifiedClean(mOrdersChangedEventHandlers); SpecifiedClean(mOnPartialCloseEventHandlers); SpecifiedClean(mPositionsChangedEventHandlers); SpecifiedClean(mTradeStateChangedEventHandlers); // string message = "DeInitialized Successfully ..."; eaAlert.SendAlert(message); // delete eaAlert; ZeroMemory(eaAlert); } /** * Handle Tick ... */ void HandleOnTick() { // // Update GUI Panel ... UpdatePanel(); // // Time Report ... HandleTimeReport(); // // Manage Trades ... eaTradeManager.Manage(); // // Manage Positions Drawings ... eaPositionDrawer.Update(); // int count = ArraySize(eaSignallers); bool has = IsValidSize(count); if (!has) { return; } // // Loop through Signallers ... for (int i = 0; i < count; i++) { // // Calling Process Ticks on Signaller ... eaSignallers[i].OnTick(0); } // HandleOnTickAdditional(); } /** * Handle Trade ... */ void HandleOnTrade() { eaTrader.HandleOnTrade(); } /** * Handle Timer ... */ void virtual HandleOnTimer() { } /** * Handle Chart Event ... * * @param id: int, Event id ... * @param lparam: long, Event Long Parameter ... * @param dparam: double, Event Double Parameter ... * @param sparam: string, Event String Parameter ... */ void virtual HandleOnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { } // // Event Triggered Listeners ... /** * Handle New Signal Recieved ... * * @param signal: XSignal, Recieved Signal ... */ void HandleOnSignalTriggered(XSignal &signal) { eaTradeManager.HandleSignal(signal); } /** * Handle Signal Executed Event ... * * @param signal: XSignal, reference to Executed Signal ... */ void HandleOnSignalExecuted(XSignal &signal) { // eaPositionDrawer.AddExecutedSignal(signal); eaTradeManager.target.AddExecutedSignal(signal); } /** * Check For Guard ... * * @param guards: XGuard, reference Collection to holds result ... * @param positions: XPosition, refrence collection to Provides Positions ... * @param barIndex: int, Specified Bar index ... * * @return ( int ) */ int CheckForGuardTriggered( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ) { // int result = 0; // if (!HasChild(eaSignallers)) { return result; } // int count = ArraySize(eaSignallers); for (int i = 0; i < count; i++) { // XGuard iGuards[]; int iGuardsCount = eaSignallers[i].CheckForGuard( iGuards, positions, barIndex // ); if (IsValidSize(iGuardsCount)) { // Copy( iGuards, guards, false // ); } // SpecifiedClean(iGuards); } // result = ArraySize(guards); // return result; } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void OnGuardedTriggered( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { eaTradeManager.HandleGuardEvent(action, positions); } /** * Check Can Analyse Market based on Time ... * * @param symbol: string, Specified Symbol ... * @param period: ENUM_TIMEFRAMES, Specified Period ... * @param time: datetime, Specified Time ... * * @return ( bool ) */ bool HandleCanAnalyseEventTriggered( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { // return eaTradeManager.CanAnalyse( symbol, period, time // ); } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void virtual HandleOnStopLossTriggered(const XDeal &deal) { // eaTradeManager.HandleSL(deal); eaPositionDrawer.HandleStopLossTriggered(deal); UpdatePanelPositionButtons(); } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void virtual HandleOnTakeProfitTriggered(const XDeal &deal) { // UpdatePanelPositionButtons(); eaTradeManager.HandleTP(deal); eaPositionDrawer.HandleOnTakeProfitTriggered(deal); } /** * Handle Position Force Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param position: XPosition instance refrence, Triggered Position ... * @param comment: string, Comment ... */ void virtual HandleOnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // UpdatePanelPositionButtons(); eaTradeManager.HandleForceClose(position); eaPositionDrawer.HandleOnPositionForceClosed( ticket, position, comment // ); } /** * Handle Position Partially Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void virtual HandleOnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaTradeManager.HandlePartiallyClosed( ticket, profit, comment // ); } /** * Handle Deals Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnDealsChanged(int count) { } /** * Handle Orders Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnOrdersChanged(int count) { } /** * Handle Positions Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnPositionsChanged(int count) { UpdatePanelPositionButtons(); } /** * Handle Position Modified Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void virtual HandleOnPositionModified( const ulong ticket, const double profit, const string comment // ) { // eaPositionDrawer.HandleOnPositionModified( ticket, profit, comment // ); } /** * Handle all Trades States Changed Event ... * * @param state: XOnTradeHandlerState instance refrence, Changed Trade State data ... */ void virtual HandleOnTradeStateChanged(const XOnTradeHandlerState &state) { } // // Validators ... /** * Validate Inputs ... * * @return ( bool ) */ bool virtual ValidateInputs() { // bool result = false; // // TODO: Handle this ... result = true; // return result; } // // Viruals ... /** * Prepare Signallers per Symbol Config ... * * @param symbolConfig: XSymbolTradeConfig, Symbol Trade Configurations ... */ void virtual PrepareSignallers(XSymbolTradeConfig &symbolConfig) { } /** * Additional On Tick Processing if Required ... * * @param barIndex: int, Specified Bar Index ... */ void virtual HandleOnTickAdditional(int barIndex = 0) { } // // Signal Event Handlers ... // void AddOnSignalEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalEventHandlers // ); } // // Add New Signal Executed Event Handler ... void AddOnSignalExecutedEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalExecutedEventHandlers // ); } // // 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 // ); } // // Protected ... protected: // // Props ... // // Actions and Tools ... /** * Report Time Changes based on Given Configurations ... */ void HandleTimeReport() { // if (eaAlert == NULL) { return; } // // Monthly Report .... if (eaReportNewMonths && eaTimeTracker.IsNewMonth()) { // string msg = "New Month ..."; // eaAlert.SendAlert(msg); } // // Weekly Report .... if (eaReportNewWeeks && eaTimeTracker.IsNewWeek()) { // string msg = "New Week ..."; // eaAlert.SendAlert(msg); } // // Daily Report .... if (eaReportNewDays && eaTimeTracker.IsNewDay()) { // string msg = "New Day ..."; // eaAlert.SendAlert(msg); } // // Hourly Report .... if (eaReportNewHours && eaTimeTracker.IsNewHour()) { // string msg = "New Hour ..."; // eaAlert.SendAlert(msg); } } /** * Register Signaller ... */ void RegisterSignaller(XCBaseSignaller *signaller) { // // Validate Signaller ... if (signaller == NULL) { return; } // // Attach Signaller OnSignal Event Handlers if Exists ... int count = ArraySize(mOnSignalEventHandlers); bool has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { signaller.AddOnSignalEventHandler(mOnSignalEventHandlers[i]); } } // // Attach Can Analyse Event Handler ... signaller.canAnalyseEventListener = canAnalyseEventHandler; // // Register Signaller ... Add( signaller, eaSignallers // ); } // // Private ... private: // // Props ... // // Specified Event Handlers ... TOnModify mOnModifyEventHandlers[]; TOnSignal mOnSignalEventHandlers[]; TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; TOnSignal mOnSignalExecutedEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; TOnDealsChanged mDealsChangedEventHandlers[]; TOnOrdersChanged mOrdersChangedEventHandlers[]; TOnPartialClose mOnPartialCloseEventHandlers[]; TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; // XCBaseSignaller *eaSignallers[]; // All Registered Signallers ... // // Panel Support ... // XCChartHelper *eaChartHelper; // Chart Helper Class ... // string objSuffix; // CButton btnBuy; CButton btnSell; CButton btnClose; CButton btnCloseAll; CEdit lblPositionId; // CButton lblTP; CButton lblSL; CButton btnSLPlus; CButton btnTPPlus; CButton btnSLMinus; CButton btnTPMinus; CButton btnSLPlusPlus; CButton btnTPPlusPlus; CButton btnSLMinusMinus; CButton btnTPMinusMinus; // CArrayObj posArray; CButton *btnSelectedPosInfo; CArrayObj selectedPosInfoArr; // ulong selectedPositionID; bool showSelectedPositionInfo; /** * Initial Management GUI Panel ... * * @return ( bool ) */ bool InitPanel() { // bool result = false; // result = !eaShowPanel; if (result) { return result; } // // Check Default Symbol and Period ... // int subWindow = 0; ulong chartId = ChartID(); objSuffix = eaLogSuffix + "_"; // // Initial Chart Class Instance ... eaChartHelper = new XCChartHelper(chartId); // int startX = 5; int startY = 25; // int defaultGap = 5; int defaultWidth = 100; int defaultHeight = 30; // // Buy ... int btnBuyX1 = startX; int btnBuyX2 = startX + defaultWidth; int btnBuyY1 = startY; int btnBuyY2 = startY + defaultHeight; string btnBuyName = objSuffix + "BTN_BUY"; result = btnBuy.Create( chartId, btnBuyName, subWindow, btnBuyX1, btnBuyY1, btnBuyX2, btnBuyY2 // ); if (result) { // // Apply Buy Button Style ... // btnBuy.Text("Buy"); btnBuy.Color(clrYellow); btnBuy.ColorBackground(clrGreen); } // // Sell ... int btnSellX1 = btnBuyX1 + btnBuyX2; int btnSellX2 = btnSellX1 + defaultWidth; int btnSellY1 = btnBuyY1; int btnSellY2 = btnBuyY2; string btnSellName = objSuffix + "BTN_SELL"; result = btnSell.Create( chartId, btnSellName, subWindow, btnSellX1, btnSellY1, btnSellX2, btnSellY2 // ); if (result) { // // Apply Sell Button Style ... // btnSell.Text("Sell"); btnSell.Color(clrYellow); btnSell.ColorBackground(clrDarkRed); } // // LABEL Position ID ... int lblPositionIdX1 = btnBuyX1; int lblPositionIdX2 = lblPositionIdX1 + defaultWidth; int lblPositionIdY1 = btnSellY2 + defaultGap; int lblPositionIdY2 = lblPositionIdY1 + defaultHeight; string lblPositionIdName = objSuffix + "LBL_POS_ID"; result = lblPositionId.Create( chartId, lblPositionIdName, subWindow, lblPositionIdX1, lblPositionIdY1, lblPositionIdX2, lblPositionIdY2 // ); if (result) { // // Apply Label Position ID Style ... lblPositionId.ReadOnly(true); lblPositionId.Text("Pos ID: "); lblPositionId.Color(clrYellow); lblPositionId.ColorBackground(clrDarkGray); } // // Close ... int btnCloseX1 = startX; int btnCloseX2 = btnCloseX1 + defaultWidth; int btnCloseY1 = lblPositionIdY2 + defaultGap; int btnCloseY2 = btnCloseY1 + defaultHeight; string btnCloseName = objSuffix + "BTN_CLOSE"; result = btnClose.Create( chartId, btnCloseName, subWindow, btnCloseX1, btnCloseY1, btnCloseX2, btnCloseY2 // ); if (result) { // // Apply Close Button Style ... // btnClose.Text("Close"); btnClose.Color(clrYellow); btnClose.ColorBackground(clrDarkOrange); } // // Close All ... int btnCloseAllX1 = btnCloseX2 + defaultGap; int btnCloseAllX2 = btnCloseAllX1 + defaultWidth; int btnCloseAllY1 = lblPositionIdY2 + defaultGap; int btnCloseAllY2 = btnCloseAllY1 + defaultHeight; string btnCloseAllName = objSuffix + "BTN_CLOSE_ALL"; result = btnCloseAll.Create( chartId, btnCloseAllName, subWindow, btnCloseAllX1, btnCloseAllY1, btnCloseAllX2, btnCloseAllY2 // ); if (result) { // // Apply Close Button Style ... // btnCloseAll.Text("Close All"); btnCloseAll.Color(clrYellow); btnCloseAll.ColorBackground(clrDarkRed); } // int minusPlusWidth = 20; // // TP Label ... int lblTPX1 = btnCloseX1; int lblTPX2 = lblTPX1 + defaultWidth; int lblTPY1 = btnCloseY2 + defaultGap; int lblTPY2 = lblTPY1 + defaultHeight; string lblTPName = objSuffix + "LBL_TP"; result = lblTP.Create( chartId, lblTPName, subWindow, lblTPX1, lblTPY1, lblTPX2, lblTPY2 // ); if (result) { // // Apply Style ... lblTP.Disable(); lblTP.Text("TP"); lblTP.Color(clrWhite); lblTP.ColorBackground(clrGreen); } // // TP Plus ... int btnTPPlusX1 = lblTPX1; int btnTPPlusX2 = btnTPPlusX1 + minusPlusWidth; int btnTPPlusY1 = lblTPY2 + defaultGap; int btnTPPlusY2 = btnTPPlusY1 + defaultHeight; string btnTPPlusName = objSuffix + "BTN_TP_PLUS"; result = btnTPPlus.Create( chartId, btnTPPlusName, subWindow, btnTPPlusX1, btnTPPlusY1, btnTPPlusX2, btnTPPlusY2 // ); if (result) { // // Apply Style ... btnTPPlus.Text("+"); btnTPPlus.Color(clrYellow); btnTPPlus.ColorBackground(clrGreen); } // // TP Plus Plus ... int btnTPPlusPlusX1 = btnTPPlusX2 + defaultGap; int btnTPPlusPlusX2 = btnTPPlusPlusX1 + minusPlusWidth; int btnTPPlusPlusY1 = lblTPY2 + defaultGap; int btnTPPlusPlusY2 = btnTPPlusPlusY1 + defaultHeight; string btnTPPlusPlusName = objSuffix + "BTN_TP_PLUSPLUS"; result = btnTPPlusPlus.Create( chartId, btnTPPlusPlusName, subWindow, btnTPPlusPlusX1, btnTPPlusPlusY1, btnTPPlusPlusX2, btnTPPlusPlusY2 // ); if (result) { // // Apply Style ... btnTPPlusPlus.Text("++"); btnTPPlusPlus.Color(clrYellow); btnTPPlusPlus.ColorBackground(clrGreen); } // // TP Minus ... int btnTPMinusX1 = lblTPX2 - minusPlusWidth; int btnTPMinusX2 = btnTPMinusX1 + minusPlusWidth; int btnTPMinusY1 = lblTPY2 + defaultGap; int btnTPMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusName = objSuffix + "BTN_TP_MINUS"; result = btnTPMinus.Create( chartId, btnTPMinusName, subWindow, btnTPMinusX1, btnTPMinusY1, btnTPMinusX2, btnTPMinusY2 // ); if (result) { // // Apply Style ... btnTPMinus.Text("-"); btnTPMinus.Color(clrYellow); btnTPMinus.ColorBackground(clrDarkRed); } // // TP Minus Minus ... int btnTPMinusMinusX1 = btnTPMinusX1 - minusPlusWidth - defaultGap; int btnTPMinusMinusX2 = btnTPMinusMinusX1 + minusPlusWidth; int btnTPMinusMinusY1 = lblTPY2 + defaultGap; int btnTPMinusMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusMinusName = objSuffix + "BTN_TP_MINUSMINUS"; result = btnTPMinusMinus.Create( chartId, btnTPMinusMinusName, subWindow, btnTPMinusMinusX1, btnTPMinusMinusY1, btnTPMinusMinusX2, btnTPMinusMinusY2 // ); if (result) { // // Apply Style ... btnTPMinusMinus.Text("--"); btnTPMinusMinus.Color(clrYellow); btnTPMinusMinus.ColorBackground(clrDarkRed); } // // SL Label ... int lblSLX1 = btnCloseAllX1; int lblSLX2 = lblSLX1 + defaultWidth; int lblSLY1 = btnCloseAllY2 + defaultGap; int lblSLY2 = lblTPY1 + defaultHeight; string lblSLName = objSuffix + "LBL_SL"; result = lblSL.Create( chartId, lblSLName, subWindow, lblSLX1, lblSLY1, lblSLX2, lblSLY2 // ); if (result) { // // Apply Style ... lblSL.Disable(); lblSL.Text("SL"); lblSL.Color(clrWhite); lblSL.ColorBackground(clrDarkRed); } // // SL Plus ... int btnSLPlusX1 = lblSLX1; int btnSLPlusX2 = btnSLPlusX1 + minusPlusWidth; int btnSLPlusY1 = lblSLY2 + defaultGap; int btnSLPlusY2 = btnSLPlusY1 + defaultHeight; string btnSLPlusName = objSuffix + "BTN_SL_PLUS"; result = btnSLPlus.Create( chartId, btnSLPlusName, subWindow, btnSLPlusX1, btnSLPlusY1, btnSLPlusX2, btnSLPlusY2 // ); if (result) { // // Apply Style ... btnSLPlus.Text("+"); btnSLPlus.Color(clrYellow); btnSLPlus.ColorBackground(clrGreen); } // // SL Plus Plus ... int btnSLPlusPlusX1 = btnSLPlusX2 + defaultGap; int btnSLPlusPlusX2 = btnSLPlusPlusX1 + minusPlusWidth; int btnSLPlusPlusY1 = lblSLY2 + defaultGap; int btnSLPlusPlusY2 = btnSLPlusPlusY1 + defaultHeight; string btnSLPlusPlusName = objSuffix + "BTN_SL_PLUSPLUS"; result = btnSLPlusPlus.Create( chartId, btnSLPlusPlusName, subWindow, btnSLPlusPlusX1, btnSLPlusPlusY1, btnSLPlusPlusX2, btnSLPlusPlusY2 // ); if (result) { // // Apply Style ... btnSLPlusPlus.Text("++"); btnSLPlusPlus.Color(clrYellow); btnSLPlusPlus.ColorBackground(clrGreen); } // // SL Minus ... int btnSLMinusX1 = lblSLX2 - minusPlusWidth; int btnSLMinusX2 = btnSLMinusX1 + minusPlusWidth; int btnSLMinusY1 = lblSLY2 + defaultGap; int btnSLMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusName = objSuffix + "BTN_SL_MINUS"; result = btnSLMinus.Create( chartId, btnSLMinusName, subWindow, btnSLMinusX1, btnSLMinusY1, btnSLMinusX2, btnSLMinusY2 // ); if (result) { // // Apply Style ... btnSLMinus.Text("-"); btnSLMinus.Color(clrYellow); btnSLMinus.ColorBackground(clrDarkRed); } // // SL Minus Minus ... int btnSLMinusMinusX1 = btnSLMinusX1 - minusPlusWidth - defaultGap; int btnSLMinusMinusX2 = btnSLMinusMinusX1 + minusPlusWidth; int btnSLMinusMinusY1 = lblSLY2 + defaultGap; int btnSLMinusMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusMinusName = objSuffix + "BTN_SL_MINUSMINUS"; result = btnSLMinusMinus.Create( chartId, btnSLMinusMinusName, subWindow, btnSLMinusMinusX1, btnSLMinusMinusY1, btnSLMinusMinusX2, btnSLMinusMinusY2 // ); if (result) { // // Apply Style ... btnSLMinusMinus.Text("--"); btnSLMinusMinus.Color(clrYellow); btnSLMinusMinus.ColorBackground(clrDarkRed); } // UpdatePanelState(); // return result; } /** * Listen For Panel Controls Events and * Update State of GUI Panel ... */ void UpdatePanel() { // if (!eaShowPanel) { return; } // UpdatePanelState(); // // Buy Button Pressed ... if (btnBuy.Pressed()) { // HandleBuyTrade(); btnBuy.Pressed(false); } // // Sell Button Pressed ... if (btnSell.Pressed()) { // HandleSellTrade(); btnSell.Pressed(false); } // // Close Button Pressed ... if (btnClose.Pressed()) { // if (btnClose.IsEnabled()) { // if (selectedPositionID > 0) { HandleCloseTrade(selectedPositionID); } } // btnClose.Pressed(false); } // // Close All Button Pressed ... if (btnCloseAll.Pressed()) { // if (btnCloseAll.IsEnabled()) { HandleCloseTrade(0); } // btnCloseAll.Pressed(false); } // // Check Show Hide Selected Position Info ... if (btnSelectedPosInfo != NULL) { // if (btnSelectedPosInfo.Pressed()) { // // Check Enable ... if (btnSelectedPosInfo.IsEnabled()) { // // Handle Toggle Show/Hide lblSelectedPositionInfo ... CEdit *iLbl = NULL; bool isVisible = showSelectedPositionInfo; int count = selectedPosInfoArr.Total(); if (IsValidSize(count)) { // // Loop Through Labels ... for (int i = 0; i < count; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); isVisible = iLbl.IsVisible(); if (isVisible) { iLbl.Hide(); } else { iLbl.Show(); } } // // Update Button Text ... isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); showSelectedPositionInfo = !showSelectedPositionInfo; } // ZeroMemory(iLbl); } // btnSelectedPosInfo.Pressed(false); } } // // TP Managing ... // // TP Plus ... if (btnTPPlus.Pressed()) { // if (btnTPPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH); } // btnTPPlus.Pressed(false); } // // TP Plus Plus ... if (btnTPPlusPlus.Pressed()) { // if (btnTPPlusPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH, 2); } // btnTPPlusPlus.Pressed(false); } // // TP Minus ... if (btnTPMinus.Pressed()) { // if (btnTPMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH); } // btnTPMinus.Pressed(false); } // // TP Minus Minus ... if (btnTPMinusMinus.Pressed()) { // if (btnTPMinusMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH, 2); } // btnTPMinusMinus.Pressed(false); } // // SL Managing ... // // SL Plus ... if (btnSLPlus.Pressed()) { // if (btnSLPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH); } // btnSLPlus.Pressed(false); } // // SL Plus Plus ... if (btnSLPlusPlus.Pressed()) { // if (btnSLPlusPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH, 2); } // btnSLPlusPlus.Pressed(false); } // // SL Minus ... if (btnSLMinus.Pressed()) { // if (btnSLMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH); } // btnSLMinus.Pressed(false); } // // SL Minus Minus ... if (btnSLMinusMinus.Pressed()) { // if (btnSLMinusMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH, 2); } // btnSLMinusMinus.Pressed(false); } // // Check Positions Buttons ... int posCount = posArray.Total(); bool has = IsValidSize(posCount); if (has) { // for (int i = 0; i < posCount; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // if (iBtn.Pressed()) { // if (iBtn.IsEnabled()) { // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); if (posID > 0 && selectedPositionID != posID) { selectedPositionID = posID; UpdatePanelState(); } } // iBtn.Pressed(false); } // ZeroMemory(iBtn); } } } /** * Update GUI Panels Controls States ... */ void UpdatePanelState() { // if (!eaShowPanel) { return; } // // Update States Of Position Select Buttons ... int count = posArray.Total(); bool has = IsValidSize(count) && selectedPositionID > 0; if (has) { // for (int i = 0; i < count; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); // // Select Position ... XPosition iPos; bool hasPosition = eaTrader.GetPosition( posID, iPos // ); string iTooltip = !hasPosition ? "" : IsLong(iPos.type) ? "Long" : "Short"; // if (posID == selectedPositionID) { // iBtn.Disable(); iBtn.ColorBackground(clrDarkGray); } else { // iBtn.Enable(); // color iBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; // iBtn.ColorBackground(iBtnBG); } // ZeroMemory(iBtn); } } // // Update State of Close All ... if (has && count > 1) { // btnCloseAll.Enable(); btnCloseAll.ColorBackground(clrDarkRed); } else { // btnCloseAll.Disable(); btnCloseAll.ColorBackground(clrDarkGray); } // // Update Selected Position Info Button State ... if (has) { // // Reading Global Chart Info ... int subWindow = 0; int chartWidth = eaChartHelper.Width(); ulong chartId = eaChartHelper.ChartId(); // // Read Selected Position ... XPosition selectedPosition; bool hasPosition = eaTrader.GetPosition( selectedPositionID, selectedPosition // ); // // Read All Positions ... double profits = 0; XPosition positions[]; string positionsInfo = ""; int positionsCount = eaTrader.GetPositions(positions); has = IsValidSize(positionsCount); if (has) { // for (int i = 0; i < positionsCount; i++) { profits += positions[i].profit; } // if (positionsCount > 1) { positionsInfo = "Positions Count: " + ToXString(positionsCount) + ", Profits: " + ToXString(profits); } } // if (hasPosition) { // // Preparing Position Info ... string posTicket = "Ticket: " + ToXString(selectedPosition.ticket); string posType = "Type: " + ToXString(selectedPosition.type); string posSymbolPeriod = "Symbol: " + selectedPosition.symbol + ", " + "Period: " + ToXString(selectedPosition.period); string posProfit = "Profit: " + ToXString(selectedPosition.profit); string posRiskToRewardRatio = "RiskToReward: " + ToXString(selectedPosition.GetRiskRewardRatio()); string accountInfo = "Balance: " + ToXString(eaTrader.mAccount.GetBalance()) + ", " + "Equity: " + ToXString(eaTrader.mAccount.GetEquity()); // string posInfos[]; // // Ticket ... Add( posTicket, posInfos // ); // // Type ... Add( posType, posInfos // ); // // Symbol Period ... Add( posSymbolPeriod, posInfos // ); // // Profit ... Add( posProfit, posInfos // ); // // Risk to Reward Ratio ... Add( posRiskToRewardRatio, posInfos // ); // // Add Positions Info if Exists ... if (IsSpecifiedValid(positionsInfo)) { // Add( positionsInfo, posInfos // ); // // Clear Info Array ... selectedPosInfoArr.Clear(); } // // Adding Account Info ... Add( accountInfo, posInfos // ); // // Create Button If Not Exists ... if (btnSelectedPosInfo == NULL) { // btnSelectedPosInfo = new CButton(); // string name = objSuffix + "BTN_TOOGLE_SPOS_INFO"; // CRect iRect = btnTPPlus.Rect(); // int x1 = iRect.left; int x2 = x1 + 200 + 5; // int y1 = iRect.bottom + 5; int y2 = y1 + iRect.Height(); // bool isCreated = btnSelectedPosInfo.Create( chartId, name, subWindow, x1, y1, x2, y2 // ); if (!isCreated) { // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } else { // // Apply Styles ... btnSelectedPosInfo.Color(clrYellow); btnSelectedPosInfo.ColorBackground(clrDarkBlue); } } // // Check Btn Exists ... has = btnSelectedPosInfo != NULL; if (has) { // int posInfoCount = ArraySize(posInfos); int lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount) && lblInfoCount == posInfoCount; // // Create info Labels ... if (!has) { // selectedPosInfoArr.Clear(); has = IsValidSize(posInfoCount); if (has) { // // Creat Info Control ... // string name = objSuffix + "LBL_SPOS_INFO"; // int lblHeight = 25; int lblWidth = 450; // int startX = chartWidth - lblWidth - 5; int sizeX = startX + lblWidth; // int startY = 5; int sizeY = startY + lblHeight; // // Loop through Position Info's Array to Create Label Controls ... for (int i = 0; i < posInfoCount; i++) { // string iText = posInfos[i]; string iTextMD5 = ToMD5(iText); // string iName = name + "_" + iTextMD5; // int iX1 = startX; int iX2 = sizeX; // int iY1 = startY; int iY2 = startY + lblHeight; // CEdit *iLbl = new CEdit(); bool isCreated = iLbl.Create( chartId, iName, subWindow, iX1, iY1, iX2, iY2 // ); if (isCreated) { // iLbl.Text(iText); iLbl.Color(clrYellow); iLbl.ColorBorder(clrDarkSlateGray); iLbl.ColorBackground(clrDarkSlateGray); // if (showSelectedPositionInfo) { iLbl.Show(); } else { iLbl.Hide(); } // selectedPosInfoArr.Add(iLbl); // startY = iY2; } } } } // // Update Info Labels ... lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount); if (has) { // CEdit *iLbl = NULL; // // Loop Through Infos ... for (int i = 0; i < lblInfoCount; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); // iLbl.Text(posInfos[i]); } // bool isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); // ZeroMemory(iLbl); } } // ZeroMemory(posInfos); } // SpecifiedClean(positions); } else { // // Toggle Selected Position Btn ... if (btnSelectedPosInfo != NULL) { // btnSelectedPosInfo.Destroy(); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } // // Selected Position Lbls ... selectedPosInfoArr.Clear(); } // // Update State of BtnClose and BtnClose All ... if (selectedPositionID == 0) { // btnClose.Disable(); btnClose.ColorBackground(clrDarkGray); // lblTP.Disable(); lblTP.ColorBackground(clrDarkGray); // btnTPPlus.Disable(); btnTPPlus.ColorBackground(clrDarkGray); // btnTPPlusPlus.Disable(); btnTPPlusPlus.ColorBackground(clrDarkGray); // btnTPMinus.Disable(); btnTPMinus.ColorBackground(clrDarkGray); // btnTPMinusMinus.Disable(); btnTPMinusMinus.ColorBackground(clrDarkGray); // lblSL.Disable(); lblSL.ColorBackground(clrDarkGray); // btnSLPlus.Disable(); btnSLPlus.ColorBackground(clrDarkGray); // btnSLPlusPlus.Disable(); btnSLPlusPlus.ColorBackground(clrDarkGray); // btnSLMinus.Disable(); btnSLMinus.ColorBackground(clrDarkGray); // btnSLMinusMinus.Disable(); btnSLMinusMinus.ColorBackground(clrDarkGray); } else { // btnClose.Enable(); btnClose.ColorBackground(clrDarkOrange); // lblTP.Enable(); lblTP.ColorBackground(clrGreen); // btnTPPlus.Enable(); btnTPPlus.ColorBackground(clrGreen); // btnTPPlusPlus.Enable(); btnTPPlusPlus.ColorBackground(clrGreen); // btnTPMinus.Enable(); btnTPMinus.ColorBackground(clrDarkRed); // btnTPMinusMinus.Enable(); btnTPMinusMinus.ColorBackground(clrDarkRed); // lblSL.Enable(); lblSL.ColorBackground(clrDarkRed); // btnSLPlus.Enable(); btnSLPlus.ColorBackground(clrGreen); // btnSLPlusPlus.Enable(); btnSLPlusPlus.ColorBackground(clrGreen); // btnSLMinus.Enable(); btnSLMinus.ColorBackground(clrDarkRed); // btnSLMinusMinus.Enable(); btnSLMinusMinus.ColorBackground(clrDarkRed); } } /** * Update Panel's Position Selector Buttons ... */ void UpdatePanelPositionButtons() { // if (!eaShowPanel) { return; } // // Retrieve Positions ... XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (!has) { // posArray.Clear(); selectedPositionID = 0; UpdatePanelState(); return; } // posArray.Clear(); // // Selected Position ID ... bool isSelectdPositionIDExists = false; if (has && selectedPositionID > 0) { // for (int i = 0; i < count; i++) { // if (!isSelectdPositionIDExists && positions[i].ticket == selectedPositionID) { // isSelectdPositionIDExists = true; break; } } } if (!isSelectdPositionIDExists || selectedPositionID == 0) { // XPosition youngest; int youngestIDX = GetXYoungest(youngest, positions); bool hasYoungest = IsValidIndex(youngestIDX) && youngest.IsValid(); if (hasYoungest) { selectedPositionID = youngest.ticket; } // youngest.Clean(); } // int subWindow = 0; ulong chartId = eaChartHelper.ChartId(); // int btnWidth = 25; int btnHeight = 25; // CRect iRect = lblPositionId.Rect(); // int lastX = iRect.left + iRect.Width() + 5; int lastSizeX = lastX + btnWidth; // int lastY = iRect.top; int lastSizeY = lastY + iRect.Height(); // for (int i = 0; i < count; i++) { // XPosition iPos = positions[i]; // string posTypeStr = IsLong(iPos.type) ? "LONG" : "SHORT"; // int iPosBtnX = lastX; int iPosBtnSizeX = iPosBtnX + btnWidth; string iPosBtnName = objSuffix + "_" + posTypeStr + "_POS_SELECT_BTN_" + ToXString(iPos.ticket); // CButton *iPosBtn = new CButton(); has = iPosBtn.Create( chartId, iPosBtnName, subWindow, iPosBtnX, lastY, iPosBtnSizeX, lastSizeY // ); if (has) { // // Apply Styles ... string iPosBtnText = ToXString(iPos.ticket); // iPosBtn.Text(iPosBtnText); iPosBtn.Color(clrWhite); // color iPosBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; iPosBtn.ColorBackground(iPosBtnBG); // lastX = iPosBtnSizeX + 5; // if (selectedPositionID == iPos.ticket) { iPosBtn.Disable(); } // posArray.Add(iPosBtn); } // iPos.Clean(); } // ZeroMemory(positions); UpdatePanelState(); // } /** * Destroy Management GUI Panel ... */ void DestroyPanel() { // delete eaChartHelper; ZeroMemory(eaChartHelper); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } // void NormalizePanelProps() { // if (eaPanelVolume < 0.01) { eaPanelVolume = 0.01; } // if (eaPanelRiskInPoint < 0) { eaPanelRiskInPoint = 50; } // if (eaPanelAllowedTPSLStep < 5) { eaPanelAllowedTPSLStep = 5; } // if (eaPanelRiskToRewardRatio < 0.5) { eaPanelRiskToRewardRatio = 2; } // if (eaPanelMinAllowedRiskInPoint < 10) { eaPanelMinAllowedRiskInPoint = 10; } } // ulong ExtractPositionIDFromButtonName(string name) { // ulong result = 0; // string nameParts[]; int namePartsCount = SplitContent(nameParts, name, "_"); bool has = IsValidSize(namePartsCount); if (has) { // string lastPart = nameParts[namePartsCount - 1]; StringReplace(lastPart, "_", ""); result = (long)lastPart; } // ZeroMemory(nameParts); // return result; } // // Management Panel Event Handlers ... // void HandleBuyTrade() { HandleTrade(X_DIRECTION_BULLISH); } // void HandleSellTrade() { HandleTrade(X_DIRECTION_BEARISH); } // void HandleTrade(ENUM_X_DIRECTION dir) { // if (!HasDirection(dir)) { return; } // NormalizePanelProps(); // bool isBullish = IsSpecifiedBullish(dir); // double _volume = eaPanelVolume; double r2r = eaPanelRiskToRewardRatio; double _riskInPoints = eaPanelRiskInPoint; double point = GetPoints(eaChartHelper.Symbol()); double entry = GetEntry(eaChartHelper.Symbol(), dir); // double risk = _riskInPoints * point; double reward = risk * r2r; // double sl = isBullish ? entry - risk : entry + risk; double tp = isBullish ? entry + reward : entry - reward; // string comment = eaLogSuffix + "_POS_" + ToXString(dir); // if (isBullish) { // eaTrader.Buy( eaChartHelper.Symbol(), eaChartHelper.Period(), _volume, entry, sl, tp, comment // ); } else { // eaTrader.Sell( eaChartHelper.Symbol(), eaChartHelper.Period(), _volume, entry, sl, tp, comment // ); } } // void HandleCloseTrade(ulong positionID) { // if (positionID == 0) { // XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (has) { // int closedCount = eaTrader.Close(positions); has = IsValidSize(closedCount); } } else { // XPosition position; bool has = eaTrader.GetPosition( positionID, position // ); if (has) { // has = eaTrader.Close(positionID); } } } // void HandleTPChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizePanelProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * eaPanelAllowedTPSLStep); // bool mustIncrease = isBullish ? isLong : !isLong; // double tp = position.tp; tp = mustIncrease ? tp + stepValue : tp - stepValue; bool isModified = eaTrader.Modify( position.ticket, position.sl, tp, objSuffix + "Change TP" // ); if (isModified) { UpdatePanelState(); } // position.Clean(); } // void HandleSLChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizePanelProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * eaPanelAllowedTPSLStep); // bool mustIncrease = isBullish ? !isLong : isLong; // double risk = position.GetRiskInPoint(); if (risk <= eaPanelMinAllowedRiskInPoint) { // position.Clean(); return; } // double sl = position.sl; sl = mustIncrease ? sl + stepValue : sl - stepValue; bool isModified = eaTrader.Modify( position.ticket, sl, position.tp, objSuffix + "Change SL" // ); if (isModified) { UpdatePanelState(); } // position.Clean(); } // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-guard.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCXGuard ... // Description: Guard Provider Class ... // Ued in XCTradeManager ... // // 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 Guard Provider Class" #property strict // // Imports ... #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5" #include "../Libraries/x-saherelm.x-guard.lib.mq5" // // Implementation ... class XCGuard : public XCBase { // // public ... public: // // Props ... double minVolumeFactorForHedge; // Minimum Volume Factor for Hedge Profit Calculation ... double minProfitPerVolumeFactorForHedge; // Minimum Required Profit per Volume Factor for Hedg ... TOnGuarded onGuardEventListener; // On Guard Event Listener ... // // Constructor(s) ... XCGuard( XCAlert *_alert, XCTrade *_trader // ) { // alert = _alert; trader = _trader; // minVolumeFactorForHedge = 0.01; minProfitPerVolumeFactorForHedge = 0.5; } // // Deconstructor(s) ... ~XCGuard() { // ZeroMemory(alert); ZeroMemory(trader); } // // Tools ... void DoGuards(XGuard &guards[]) { // bool has = HasChild(guards); if (!has) { return; } // XGuard tmp[]; Copy( guards, tmp // ); while (HasChild(tmp)) { // XGuard iGuard = tmp[0]; ArrayRemove( tmp, 0, 1 // ); // // Do Guard Action ... DoGuard(iGuard); } // Clean(tmp); } // void DoGuard(XGuard &guard) { // bool has = false; // // Validate and Do Guard ... has = guard.IsValid(); if (!has) { return; } // // Switch Based on Guard Action ... switch (guard.action) { // // Close ... case X_GUARD_ACTION_CLOSE: DoClose(guard); break; // // Close All ... case X_GUARD_ACTION_CLOSE_ALL: DoCloseAll(guard); break; // // Close All Long Positions ... case X_GUARD_ACTION_CLOSE_LONGS: DoCloseLongs(guard); break; // // Close All Short Positions ... case X_GUARD_ACTION_CLOSE_SHORTS: DoCloseShorts(guard); break; // // Close In Losts ... case X_GUARD_ACTION_CLOSE_IN_LOSTS: DoCloseInLosts(guard); break; // // Close In Profits ... case X_GUARD_ACTION_CLOSE_IN_PROFITS: DoCloseInProfits(guard); break; // // Close In Lost Longs ... case X_GUARD_ACTION_CLOSE_IN_LOST_LONGS: DoCloseInLostLongs(guard); break; // // Close In Profit Longs ... case X_GUARD_ACTION_CLOSE_IN_PROFIT_LONGS: DoCloseInProfitLongs(guard); break; // // Close In Lost Shorts ... case X_GUARD_ACTION_CLOSE_IN_LOST_SHORTS: DoCloseInLostShorts(guard); break; // // Close In Profit Shorts ... case X_GUARD_ACTION_CLOSE_IN_PROFITS_SHORT: DoCloseInProfitShorts(guard); break; // // Partial Close ... case X_GUARD_ACTION_PARTIAL_CLOSE: DoPartialClose(guard); break; // // Trail Stop ... case X_GUARD_ACTION_TRAIL_STOP: DoTrailStop(guard); break; // // Trail Target ... case X_GUARD_ACTION_TRAIL_TARGET: DoTrailTarget(guard); break; // // Hedge Positions ... case X_GUARD_ACTION_HEDGE: DoHedge(guard); break; // } } // // protected ... protected: // // bool GetPosition( XPosition &position, XGuard &guard // ) { // bool result = false; // position.Clean(); // result = guard.IsValid() && guard.ticket > 0; if (!result) { return result; } // // Get Position ... result = trader.GetPosition( guard.ticket, position // ); if (!result) { // position.Clean(); // return result; } // // Validate Position ... result = position.IsValid() && position.symbol == guard.symbol && position.provider == guard.provider && position.period == guard.period; if (!result) { // position.Clean(); // return result; } // return result; } // int GetPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // result = trader.GetPositions( positions, guard.symbol, guard.provider, guard.period, NULL, // All Types ... true, // Filter By Magc ... true // Force Clean ... ); // result = ArraySize(positions); // return result; } // int GetLongPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // result = trader.GetPositions( positions, guard.symbol, guard.provider, guard.period, X_POSITION_TYPE_LONG, // Specified Types ... true, // Filter By Magc ... true // Force Clean ... ); // result = ArraySize(positions); // return result; } // int GetShortPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // result = trader.GetPositions( positions, guard.symbol, guard.provider, guard.period, X_POSITION_TYPE_SHORT, // Specified Types ... true, // Filter By Magc ... true // Force Clean ... ); // result = ArraySize(positions); // return result; } // int GetInProfitPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit > 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // int GetInLostPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit < 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // int GetInProfitLongPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetLongPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit > 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // int GetInLostLongPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetLongPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit < 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // int GetInProfitShortPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetShortPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit > 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // int GetInLostShortPositions( XPosition &positions[], XGuard &guard // ) { // int result = 0; // Clean(positions); // bool has = guard.IsValid(); if (!has) { return result; } // XPosition allPositions[]; int allPositionsCount = GetShortPositions( allPositions, guard // ); has = IsValidSize(allPositionsCount); if (!has) { return result; } // while (HasChild(allPositions)) { // XPosition iPosition = allPositions[0]; ArrayRemove( allPositions, 0, 1 // ); // if (iPosition.profit < 0) { // AddRef( iPosition, positions // ); } // iPosition.Clean(); } Clean(allPositions); // result = ArraySize(positions); // return result; } // // Guard Handlers ... // void DoClose(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... // // Validate Action and Requirements ... has = NotEmpty(guard.ticket) && guard.action == X_GUARD_ACTION_CLOSE; if (!has) { return; } // // Retrieve Position ... XPosition position; has = GetPosition( position, guard // ); if (!has) { // position.Clean(); // return; } // string comment = "Guard Close ..."; // has = trader.Close( position.ticket, comment // ); if (has) { // HandleNotifyPositionGuard(guard.action, position); // string message = "Guard Closed " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // position.Clean(); } // void DoCloseAll(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_ALL; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInLosts(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_LOSTS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInLostPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Losts ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " In Lost Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInProfits(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_PROFITS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInProfitPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Profits ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " In Profit Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseLongs(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_LONGS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetLongPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close Longs ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " Long Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInLostLongs(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_LOST_LONGS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInLostLongPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Lost Longs ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " In Lost Longs Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInProfitLongs(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_PROFIT_LONGS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInProfitLongPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Profit Longs ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " In Profit Longs Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseShorts(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetShortPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close Shorts ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " Long Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInLostShorts(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_LOST_SHORTS; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInLostShortPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Lost Shorts ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Closed " + ToXString(count) + " In Lost Shorts Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoCloseInProfitShorts(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... has = guard.action == X_GUARD_ACTION_CLOSE_IN_PROFITS_SHORT; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetInProfitShortPositions( positions, guard // ); has = IsValidSize(count); if (!has) { // Clean(positions); // return; } // string comment = "Guard Close All In Profit Shorts ..."; // has = trader.Close( positions, comment // ); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // // string message = "Guard Closed " + ToXString(count) + " In Profit Shorts Positions Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // void DoPartialClose(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... // // Validate Action and Requirements ... has = NotEmpty(guard.ticket) && guard.volumeMultiplier > 0 && guard.action == X_GUARD_ACTION_PARTIAL_CLOSE; if (!has) { return; } // // Retrieve Position ... XPosition position; has = GetPosition( position, guard // ); if (!has) { // position.Clean(); // return; } // // Normalize Volume Multiplier ... double vMult = guard.volumeMultiplier; if (vMult > 0.5) { vMult = 0.5; } if (vMult < 0) { vMult = 0.5; } // // Calculate and Normalize Volume ... double volume = position.volume * vMult; volume = NormalizeVolume( volume, position.symbol // ); // string comment = "Guard Partially Closed: " + ToXString(volume) + " ..."; // has = trader.ClosePartial( position.ticket, volume, comment // ); if (has) { // HandleNotifyPositionGuard(guard.action, position); // string message = "Guard Closed Partially " + ToXString(volume) + " of " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // position.Clean(); } // void DoTrailStop(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... // // Validate Action and Requirements ... has = guard.sl >= 0 && NotEmpty(guard.ticket) && (guard.sl <= 0 ? guard.force : true) && guard.action == X_GUARD_ACTION_TRAIL_STOP; if (!has) { return; } // // Normalize SL ... if (guard.sl < 0) { guard.sl = 0; } // // Retrieve Position ... XPosition position; has = GetPosition( position, guard // ); if (!has) { // position.Clean(); // return; } // bool isLong = IsLong(position.type); bool isGuardPassed = guard.sl > 0 ? (isLong ? position.price > guard.sl && (position.sl == 0 || position.sl < guard.sl) : position.price < guard.sl && (position.sl == 0 || position.sl > guard.sl)) : (guard.sl == 0 && guard.force); // // Check Can Trail Stop or not ... has = // // Position Exists ... has && // // Positions in Profit for Trailling Stop ... position.profit > 0 && // // Validate SL based on Position Type ... isGuardPassed; if (!has) { // position.Clean(); // return; } // string comment = "Guard Trail Stop ..."; // has = trader.Modify( position.ticket, guard.sl, position.tp, comment // ); if (has) { // HandleNotifyPositionGuard(guard.action, position); // double before = NormalizePrice(position.sl, position.symbol); double after = NormalizePrice(guard.sl, position.symbol); // string message = "Guard Trail Stop " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ")" + " From: " + ToXString(before) + "To: " + ToXString(after) + " Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // position.Clean(); } // void DoTrailTarget(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... // // Validate Action and Requirements ... has = guard.tp >= 0 && NotEmpty(guard.ticket) && (guard.tp <= 0 ? guard.force : true) && guard.action == X_GUARD_ACTION_TRAIL_TARGET; if (!has) { return; } // // Normalize ... if (guard.tp < 0) { guard.tp = 0; } // // Retrieve Position ... XPosition position; has = GetPosition( position, guard // ); if (!has) { // position.Clean(); // return; } // bool isLong = IsLong(position.type); bool isGuardPassed = guard.tp > 0 ? (isLong ? guard.tp > position.price : guard.tp < position.price) : (guard.tp == 0 && guard.force); // // Check Can Trail Stop or not ... has = // // Position Exists ... has && // // Check TP is not Same ... guard.tp != position.tp && // // Validate TP based on Current Price ... isGuardPassed; if (!has) { // position.Clean(); // return; } // string comment = "Guard Trail Target ..."; // has = trader.Modify( position.ticket, position.sl, guard.tp, comment // ); if (has) { // HandleNotifyPositionGuard(guard.action, position); // double before = NormalizePrice(position.tp, position.symbol); double after = NormalizePrice(guard.tp, position.symbol); // string message = "Guard Trail Target " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ")" + " From: " + ToXString(before) + "To: " + ToXString(after) + " Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // position.Clean(); } // void DoHedge(XGuard &guard) { // bool has = false; // has = guard.IsValid(); if (!has) { return; } // // Do What we want ... // // Validate Action and Requirements ... has = (guard.force ? true : (minVolumeFactorForHedge > 0 && minProfitPerVolumeFactorForHedge > 0)) && guard.action == X_GUARD_ACTION_HEDGE; if (!has) { return; } // // Retrieve Positions ... XPosition positions[]; int count = GetPositions( positions, guard // ); has = HasChild(positions); if (!has) { // Clean(positions); // return; } // // Calculate Positions Profits and Volumes ... double swaps = 0; double profits = 0; double volumes = 0; double commissions = 0; for (int i = 0; i < count; i++) { // swaps += positions[i].swap; profits += positions[i].profit; volumes += positions[i].volume; commissions += positions[i].commission; } // // Check Profits and Volumes for Hedging ... double hedgeValue = profits + (-1 * swaps) + commissions; // // Check Force Hedging ... if (!guard.force) { // // Calculate Minimum Required Profit for Hedging ... double minRequiredProfit = (volumes / minVolumeFactorForHedge) * minProfitPerVolumeFactorForHedge; // has = hedgeValue >= minRequiredProfit; } else { has = hedgeValue > 0; } // if (!has) { // Clean(positions); // return; } // string comment = "Guard Hedge ..."; // // Loop through Positions and Close them One by One ... // this is because of Trade Manager to Handle Close Trades ... int closedCount = 0; for (int i = 0; i < count; i++) { // has = trader.Close( positions[i].ticket, comment // ); if (has) { closedCount++; } } // has = IsValidSize(closedCount); if (has) { // HandleNotifyPositionsGuard(guard.action, positions); // string message = "Guard Hedge " + ToXString(closedCount) + " Positions by: " + ToXString(hedgeValue) + " Successfully ..."; // alert.SendAlert(message); } // // Cleanup Resources ... // Clean(positions); } // // private ... private: // XCTrade *trader; XCAlert *alert; // void HandleNotifyPositionGuard( ENUM_X_GUARD_ACTIONS action, XPosition &position // ) { // if (!IsSpecifiedValid(action) || !position.IsValid() || onGuardEventListener == NULL) { return; } // XPosition positions[]; AddRef( position, positions // ); HandleNotifyPositionsGuard(action, positions); } // void HandleNotifyPositionsGuard( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { // if (!IsSpecifiedValid(action) || !HasChild(positions) || onGuardEventListener == NULL) { return; } // onGuardEventListener(action, positions); } // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-helper.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCBaseHelper // Description: provides all Base Indicator // Helper requirements ... // // // 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 // // Includes ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... enum ENUM_X_SCORE { X_SCORE_NONE = 0, X_SCORE_MIN = 1, X_SCORE_NORMAL = 2, X_SCORE_MAX = 3, }; // #region Generics ... // // State Handler Generic Functions ... #define DECLARE_STATE_FUNCTIONS(name, state_reader, bar_normalizer_func) \ bool Is##name##Bullish(int barIndex = 0) \ { \ barIndex = bar_normalizer_func(barIndex); \ return state_reader(barIndex) >= 1; \ } \ bool Is##name##Bearish(int barIndex = 0) \ { \ barIndex = bar_normalizer_func(barIndex); \ return state_reader(barIndex) <= -1; \ } \ bool Is##name##SwitchedToBullish(int barIndex = 0) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##Bullish(barIndex) && !Is##name##Bullish(barIndex + 1); \ } \ bool Is##name##SwitchedToBearish(int barIndex = 0) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##Bearish(barIndex) && !Is##name##Bearish(barIndex + 1); \ } // // State Handler Based On Price Type Generic Functions ... #define DECLARE_PRICE_BASED_STATE_FUNCTIONS(name, value_reader, bar_normalizer_func, point_reader_func, price_reader_func) \ bool Is##name##Bullish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ double threshold = point_reader_func() * tolerance; \ return price_reader_func(barIndex, priceType) > value_reader(barIndex) + threshold || \ price_reader_func(barIndex, priceType) > value_reader(barIndex) - threshold; \ } \ bool Is##name##Bearish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ double threshold = point_reader_func() * tolerance; \ return price_reader_func(barIndex, priceType) < value_reader(barIndex) + threshold || \ price_reader_func(barIndex, priceType) < value_reader(barIndex) - threshold; \ } \ bool Is##name##SwitchedToBullish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##Bullish(barIndex, priceType, tolerance) && !Is##name##Bullish(barIndex + 1, priceType, tolerance); \ } \ bool Is##name##SwitchedToBearish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##Bearish(barIndex, priceType, tolerance) && !Is##name##Bearish(barIndex + 1, priceType, tolerance); \ } // // Value Comparator Generic Functions ... #define DECLARE_VALUE_COMPARATOR_FUNCTIONS(name, value_reader, bar_normalizer_func, point_reader_func) \ bool Is##name##OverLast(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return IsOver( \ value_reader(barIndex), \ value_reader(barIndex + 1), \ point_reader_func() * tolerance); \ } \ bool Is##name##UnderLast(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return IsUnder( \ value_reader(barIndex), \ value_reader(barIndex + 1), \ point_reader_func() * tolerance); \ } \ bool Is##name##SameAsLast(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return IsSame( \ value_reader(barIndex), \ value_reader(barIndex + 1), \ point_reader_func() * tolerance); \ } \ bool Is##name##CrossedOverLast(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##OverLast(barIndex, tolerance) && !Is##name##OverLast(barIndex + 1, tolerance); \ } \ bool Is##name##CrossedUnderLast(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##name##UnderLast(barIndex, tolerance) && !Is##name##UnderLast(barIndex + 1, tolerance); \ } // // Price Comparator Generic Functions ... #define DECLARE_PRICE_COMPARATOR_FUNCTIONS(name, value_reader, bar_normalizer_func, price_reader_func) \ bool IsPriceOver##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \ { \ barIndex = bar_normalizer_func(barIndex); \ return price_reader_func(barIndex, priceType) > value_reader(barIndex); \ } \ bool IsPriceUnder##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \ { \ barIndex = bar_normalizer_func(barIndex); \ return price_reader_func(barIndex, priceType) < value_reader(barIndex); \ } \ bool IsPriceCrossedOver##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \ { \ barIndex = bar_normalizer_func(barIndex); \ return IsPriceOver##name(barIndex, priceType) && !IsPriceOver##name(barIndex + 1, priceType); \ } \ bool IsPriceCrossedUnder##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \ { \ barIndex = bar_normalizer_func(barIndex); \ return IsPriceUnder##name(barIndex, priceType) && !IsPriceUnder##name(barIndex + 1, priceType); \ } // // Crossing Comparator Generic Functions ... #define DECLARE_CROSSING_COMPARATOR_FUNCTIONS(baseName, fastName, slowName, fast_reader_func, slow_reader_func, bar_normalizer_func, point_reader_func) \ bool Is##baseName##fastName##Over##Slow(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ double fast = fast_reader_func(barIndex); \ double slow = slow_reader_func(barIndex); \ double distance = tolerance * point_reader_func(); \ return fast > slow && MathAbs(fast - slow) >= distance; \ } \ bool Is##baseName##fastName##Under##Slow(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ double fast = fast_reader_func(barIndex); \ double slow = slow_reader_func(barIndex); \ double distance = tolerance * point_reader_func(); \ return fast < slow && MathAbs(fast - slow) >= distance; \ } \ bool Is##baseName##fastName##CrossedOver##Slow(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##baseName##fastName##Over##Slow(barIndex, tolerance) && !Is##baseName##fastName##Over##Slow(barIndex + 1, tolerance); \ } \ bool Is##baseName##fastName##CrossedUnder##Slow(int barIndex = 0, double tolerance = 2) \ { \ barIndex = bar_normalizer_func(barIndex); \ return Is##baseName##fastName##Under##Slow(barIndex, tolerance) && !Is##baseName##fastName##Under##Slow(barIndex + 1, tolerance); \ } // #endregion // // a Class for Handle base requirements ... // for indicators ... class XCBaseHelper : public XCBase { // // Public ... public: // // Constructor ... XCBaseHelper( string symbol, // Trading Symbol ENUM_TIMEFRAMES period // Trading Time Frame ) { // mSymbol = symbol; mPeriod = period; } // // Deconstructor ... ~XCBaseHelper() { // IndicatorRelease(mHandler); } // // Setter(s) / Getter(s) ... // // Symbol ... string GetSymbol() { return mSymbol; } // // Period ... ENUM_TIMEFRAMES GetPeriod() { return mPeriod; } // // Retrieve Bars ... int CountBars() { // int result = Bars( mSymbol, mPeriod // ); // return result; } // // Retrieve Indicator Calculated Bars ... int CountCalculatedBars() { return BarsCalculated(mHandler); } // virtual void Free() { } // // Generate Tag ... virtual string GetTag() { // string result = NULL; // result = // GetToken() + "[" + GetSymbol() + "|" + ToXString(GetPeriod()) + "]" // ; // return result; } // // Functions ... /** * Validate Handler Exists ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = IsXValid(mSymbol) && IsXValid(mPeriod) && mHandler != INVALID_HANDLE; // return result; } /** * Extract Validated Zones ... * * @param zones: XBoxZone, collection reference to holds results ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFZones: int, required Number of Zones ... * @param breakValidLength: int, Breake Validation Length of Zones ... * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... * @param shadowMultiplier: double a Shadow Multiplier for Validation ... * @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ... * @param validationLength: int, Validation Length of Zones ... * @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ... * * @return ( int ) */ int ExtractBarZones( XBoxZone &zones[], int barIndex = 0, int requiredNumberOFZones = 50, int breakValidLength = 3, bool validateFakeBreakes = true, double shadowMultiplier = 3, double validationStrength = 1, int validationLength = 21, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... SpecifiedClean(zones); // // Normalize ... barIndex = NormalizeInt(barIndex, 0); validationLength = NormalizeInt(validationLength, 7); shadowMultiplier = NormalizeDouble(shadowMultiplier, 1); validationStrength = NormalizeDouble(validationStrength, 1); requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100); // // Reading Values ... // string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); double minAllowedStrength = (validationStrength * GetPoints(symbol)); // XOHCL bar; bool has = false; // // Initialized Start Bar ... has = bar.Init( symbol, period, barIndex // ); if (!has) { return result; } // XOHCL iBar; XBoxZone zone; int start = barIndex; bool isBullish = false; bool isBearish = false; bool lowShadowPassed = false; bool highShadowPassed = false; ENUM_X_DIRECTION dir = X_DIRECTION_NONE; int end = start + maxAllowedLoopbackLength; for (int i = start; i < end; i++) { // // Cleanup ... iBar.Clean(); zone.Clean(); dir = X_DIRECTION_NONE; // // Reading HK Buffesr ... has = bar.BarAt(i, iBar); if (!has) { continue; } // // Check Direction ... isBullish = iBar.open < iBar.close; isBearish = iBar.open > iBar.close; dir = (isBullish && !isBearish) ? X_DIRECTION_BULLISH : (isBearish && !isBullish) ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; has = HasDirection(dir); if (!has) { continue; } // // Low Shadow ... lowShadowPassed = iBar.GetLowShadow() >= (shadowMultiplier * iBar.GetHighShadow()); // // High Shadow ... highShadowPassed = iBar.GetHighShadow() >= (shadowMultiplier * iBar.GetLowShadow()); // has = (lowShadowPassed && !highShadowPassed) || (highShadowPassed && !lowShadowPassed); if (!has) { continue; } // // Filling Zone ... // zone.symbol = symbol; zone.period = period; zone.from = GetBarTime( zone.symbol, zone.period, i // ); zone.dir = lowShadowPassed ? X_DIRECTION_BULLISH : highShadowPassed ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; // zone.upper = IsXBullish(zone.dir) ? iBar.GetDown() : IsXBearish(zone.dir) ? iBar.high : EMPTY_VALUE; // zone.lower = IsXBullish(zone.dir) ? iBar.low : IsXBearish(zone.dir) ? iBar.GetUp() : EMPTY_VALUE; // zone.to = bar.time; zone.type = "XBar_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" : "") + "_" + ToXString(TimeToSeconds(zone.from)); // // Validate ... has = zone.IsValid() && HasDirection(zone.dir) && NotEmptyZero(zone.upper) && NotEmptyZero(zone.lower) && (zone.IsBullish() ? bar.low > zone.upper : bar.high < zone.lower) && (zone.upper - zone.lower) >= minAllowedStrength && ValidateBarZone(zone, validationLength, breakValidLength, validateFakeBreakes); if (has) { // AddIfNotExists( zone, zones // ); } // // Cleanup Resources ... zone.Clean(); // // Validating ... result = ArraySize(zones); has = IsValidSize(result) && result >= requiredNumberOFZones; if (has) { break; } } // // Cleanup Resources ... bar.Clean(); iBar.Clean(); zone.Clean(); // return result; } /** * Validate Bar Zone ... * * @param zone: XBoxZone, reference to Specified Zone ... * @param validationLength: int, Validation Length of Zones ... * @param breakValidLength: int, Break Validation Length of Zones ... * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... * * @return ( bool ) */ bool ValidateBarZone( XBoxZone &zone, int validationLength = 1, int breakValidLength = 3, bool validateFakeBreakes = true // ) { // bool result = false; // // Normalize ... validationLength = NormalizeInt(validationLength, 1); breakValidLength = NormalizeInt(breakValidLength, 2); // // Validate ... result = zone.IsValid(); if (!result) { return result; } // // Requirements ... XOHCL iBar; int count = 0; string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); // int start = zone.FromIndex() + 1; int end = start + validationLength; // // Validate Before ... for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, i // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.low > zone.lower : iBar.high < zone.upper; if (!result) { break; } } // // Validating After ... if (result) { // start = zone.ToIndex() + 1; count = zone.FromIndex() - start; end = start + count; for (int i = start; i < end; i++) { // // Initialized Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, i // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.low > zone.lower : iBar.high < zone.upper; if (!result) { // // Check For Fake Breake ... if (validateFakeBreakes && breakValidLength > 0) { // result = i - 1 >= 0; if (result) { // for (int j = i - 1; j >= zone.ToIndex(); j--) { // // Initialized Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, j // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.close > zone.upper : iBar.close < zone.lower; if (result) { // result = MathAbs(j - i) <= breakValidLength; if (result) { break; } } } } } // if (!result) { break; } } } } // // Cleanup Resource ... iBar.Clean(); // return result; } /** * Normalizing Bar Index ... * * @param barIndex: int, Provided Bar Index ... * * @return ( int ) */ int NormalizeBarIndex(int barIndex) { // int result = barIndex; // if (!IsValid()) { return result; } // int count = CountBars() - 1; result = NormalizeInt(result, 0, count - 1); // return result; } // // Protected ... protected: // // Props ... // // Symbol ... string mSymbol; // // Period ... ENUM_TIMEFRAMES mPeriod; // // Indicator Handler ... int mHandler; /** * Read Value of Specified Buffer ... * * @param bufferIndex: int, which handler buffer to read value ... * @param barIndex: int, Specified Bar Index ... * * @return ( double ) */ double ReadValue( int bufferIndex, int barIndex = 0 // ) { // double result = EMPTY_VALUE; // // Normalize ... int barsTotal = CountBars(); barIndex = NormalizeInt(barIndex, 0, barsTotal - 1); bufferIndex = NormalizeInt(bufferIndex, 0); // // Validate ... if (!IsValid()) { return result; } // double tmp[]; int count = CopyBuffer( mHandler, bufferIndex, barIndex, 1, tmp // ); result = tmp[0]; // return result; } /** * Read Values of Specified Buffer ... * * @param buffer: double, reference collection to holds result ... * @param bufferIndex: int, which handler buffer to read value ... * @param barIndex: int, Specified Bar Index ... * @param count: int, number of items to read, 0 for WHOLE_ARRAY ... * @param asSeries: bool, set As Series Buffer or not ... * * @return ( int ) */ int ReadValues( double &buffer[], int bufferIndex, int barIndex = 0, int count = 0, bool asSeries = true // ) { // int result = 0; // // Prepare ... XClean(buffer); // // Normalize ... int barsTotal = CountBars(); count = NormalizeInt(count, 0); bufferIndex = NormalizeInt(bufferIndex, 0); barIndex = NormalizeInt(barIndex, 0, barsTotal - 1); // // Validate ... if (!IsValid()) { return result; } // result = CopyBuffer( mHandler, bufferIndex, barIndex, count, buffer // ); // // Set As Series Flag ... ArraySetAsSeries(buffer, asSeries); // result = ArraySize(buffer); // return result; } // // Private ... private: // }; // // Tools .... ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-http.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCHttp // Description: provides all HTTP requirements ... // // // 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 // // Definitions ... // enum X_HTTP_METHOD { X_HTTP_GET, X_HTTP_POST }; // // Imports ... // // Includes ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // // a Class for Manage Account ... class XCHttp : public XCBase { // // Public ... public: // // Constructor ... XCHttp() { XCHttp("", 10000); } XCHttp( string path, // Base Folder to Store Data int timeout // base timeout for Requests ) { // Path(path); Timeout(timeout); } // // Deconstructor ... ~XCHttp() { } // // Properties Getter(s) / Setter(s) ... // // Path ... void Path(string value) { // mPath = value; // if (!IsValid(mPath)) { mPath = GetTag(); } } string Path() { return mPath; } // // Timeout ... void Timeout(int value) { mTimeout = value; } // int Timeout() { return mTimeout; } // // Error ... int Error() { return mError; } // // Response ... string Response() { return mResponse; } // // Overrides ... string GetTag() override { return GetSpecificToken(this); } // // Tools ... // // Send Global Request ... int SendRequest( X_HTTP_METHOD method, // Httm Request Method const string url, // Server Address const string headers, // Headers providing const char &payload[], // the Data which needs to Send char &response[], // Response of request string responseHeaders, // Response Headers int timeout = 500 // Timeout for response default is 500 ) { // int result = -1; // string strMethod = ToString(method); if (StringLen(strMethod) == 0) { return result; } // // Reset State ... ResetState(); // result = WebRequest( strMethod, url, headers, timeout, payload, response, responseHeaders); // if (result < 0) { mError = GetLastError(); } else { mResponse = CharArrayToString(response); } // return result; } // // Get Request ... int GetRequest( const string url, // Server Address const string headers, // Headers providing const char &payload[], // the Data which needs to Send char &response[], // Response of request string responseHeaders, // Response Headers int timeout = 500 // Timeout for response default is 500 ) { // int result = SendRequest( X_HTTP_GET, url, headers, payload, response, responseHeaders, timeout); // return result; } // // Post Request ... int PostRequest( const string url, // Server Address const string headers, // Headers providing const char &payload[], // the Data which needs to Send char &response[], // Response of request string responseHeaders, // Response Headers int timeout = 500 // Timeout for response default is 500 ) { // int result = SendRequest( X_HTTP_POST, url, headers, payload, response, responseHeaders, timeout); // return result; } // // Handle Download Specific URL Content to Specific Path and File Name ... bool Download( string url, // the URL address which going to download string fileName // Specify Destination file name to Store Response ) { // bool result = false; // string filePath = GetFilePath(fileName); string cookie = NULL; string referer = NULL; int timeout = Timeout(); // char payload[]; string headers; char response[]; string responseHeaders; // // Send Request ... int requestResult = GetRequest( url, headers, payload, response, responseHeaders, timeout); // // Define File Handler ... int mFileHandler = FileOpen( filePath, FILE_WRITE | FILE_BIN); if (mFileHandler == INVALID_HANDLE) { // mError = GetLastError(); return result; } // // Write Response to File ... uint writed = FileWriteArray( mFileHandler, response, 0, ArraySize(response)); FileFlush(mFileHandler); FileClose(mFileHandler); // result = writed > 0; // return result; } // // END Provided Functions ... // // // Protected ... protected: // // Destintion Folder Path ... string mPath; // // WEB Request Timeout Value ... int mTimeout; // // WEB Request's Response ... string mResponse; // // Error Value ... int mError; // // Private ... private: // // Reset Errors State ... void ResetState() { // // Reset Errors ... mError = -1; mResponse = ""; ResetLastError(); } // // Generate Full File Path ... string GetFilePath(string fileName) { // string result = ""; // result = // Path() + "\\" + fileName // ; // return result; } }; // // Tools ... // // Convert enum to String ... string ToString(X_HTTP_METHOD method) { // string result = ""; // switch (method) { // case X_HTTP_GET: result = "GET"; break; // case X_HTTP_POST: result = "POST"; break; } // return result; } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-market.pattern.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XCMarketPatternDetector // Description: provides all Alerts requirements ... // // // 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-bar.analyser.class.mq5" #include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" // // Definitions ... // // Implementation ... class XCMarketPatternDetector : public XCBase { // // Public ... public: // // Props ... // // Constructor ... XCMarketPatternDetector() { barAnalyser = new XCBarAnalyser(); } // // Deconstructor ... ~XCMarketPatternDetector() { // delete barAnalyser; ZeroMemory(barAnalyser); } // // Analysers ... /** * Check for Price Touch Support Level ... * * @param bar: XOHCL, Specified Bar ... * @param supportBar: XOHCL, reference to holds Zone Bar ... * @param supportBox: XBoxZone, reference to holds Zone Box ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool IsSupportTouched( XOHCL &bar, XOHCL &supportBar, XBoxZone &supportBox, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // bool result = false; // // Prepare ... supportBar.Clean(); supportBox.Clean(); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Check Support Exists ... result = HasSupport( bar, supportBar, validationLength, maxAllowedLoopback // ); if (!result) { // supportBar.Clean(); return result; } // // Extract Support Box ... result = ToSupportBox( supportBar, supportBox // ); // // Retrieve Previous Bar ... XOHCL pBar; result = result && bar.GetPreviousBar(pBar); // // Chekc Price of Bar ... result = result && pBar.low < supportBox.upper; // // Cleanup Resources ... if (!result) { // supportBar.Clean(); supportBox.Clean(); } pBar.Clean(); // return result; } /** * Check for Price Touch Resistance Level ... * * @param bar: XOHCL, Specified Bar ... * @param supportBar: XOHCL, reference to holds Zone Bar ... * @param supportBox: XBoxZone, reference to holds Zone Box ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool IsResistanceTouched( XOHCL &bar, XOHCL &resistanceBar, XBoxZone &resistanceBox, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // bool result = false; // // Prepare ... resistanceBar.Clean(); resistanceBox.Clean(); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Check Resistance Exists ... result = HasResistance( bar, resistanceBar, validationLength, maxAllowedLoopback // ); if (!result) { // resistanceBar.Clean(); return result; } // // Extract Resistance Box ... result = ToResistanceBox( resistanceBar, resistanceBox // ); // // Retrieve Previous Bar ... XOHCL pBar; result = result && bar.GetPreviousBar(pBar); // // Chekc Price of Bar ... result = result && pBar.high > resistanceBox.lower; // // Cleanup Resources ... if (!result) { // resistanceBar.Clean(); resistanceBox.Clean(); } pBar.Clean(); // return result; } /** * Check a Bar has Same Sequence Directionalo Bar or Not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION, Detected Bars Direction ... * @param count: int, Number of Same Bars ... * @param validation: int, Validation of Same Bars ... * @param loopback: int, Loopback for Detection ... * * @return ( bool ) */ bool HasSameBars( XOHCL &bar, ENUM_X_DIRECTION &dir, int &count, int validation = 3 // ) { // bool result = false; // // Normalize ... count = 0; dir = X_DIRECTION_NONE; // // Validate ... result = bar.IsValid() && validation > 1; if (!result) { return result; } // XOHCL tmpBar; bar.GetPreviousBar(tmpBar); while ((tmpBar.GetDirection() == bar.GetDirection()) || ((bar.IsBullish() && !tmpBar.IsBearish()) || (bar.IsBearish() && !tmpBar.IsBullish()))) { // count++; tmpBar.GetPreviousBar(tmpBar); } // // Validate Count ... result = count >= validation; if (result) { dir = bar.GetDirection(); } // result = result && count > 0 && HasDirection(dir) && count >= validation; // tmpBar.Clean(); // return result; } /** * Detect Confluence Statck based on Given Bar ... * * @param bar: XOHCL, Specified Bar for Start Detection ... * @param zone: XBoxZone, confluence Zone, if exists ... * @param forDir: ENUM_X_DIRECTION, Specified Required Zone Confluence ... * @param retests: int, Number of Zone retesting ... * @param loopback: int, Max allowed Loopback for Confluence Detection ... * @param rangeLength: int, Loopback for Range Detecttion ... * @param upperPriceType: ENUM_X_PRICE, zone upper Price Type ... * @param lowerPriceType: ENUM_X_PRICE, * @return ( bool ) */ bool HasConfluence( XOHCL &bar, XBoxZone &confluence, ENUM_X_DIRECTION forDir, int retests = 2, int loopback = 15, int rangeLength = 5, ENUM_X_PRICE upperPriceType = X_PRICE_HIGH, ENUM_X_PRICE lowerPriceType = X_PRICE_LOW // ) { // bool result = false; // // Normalize ... confluence.Clean(); if (retests < 0) { retests = 0; } if (loopback < 2) { loopback = 2; } if (rangeLength < 2) { rangeLength = 2; } // // Validate ... result = bar.IsValid() && HasDirection(forDir) && IsXValid(upperPriceType) && IsXValid(lowerPriceType); if (!result) { return result; } // // Retrieve Upper and Lower ... int mIndex = -1; double upper = bar.FindHighest( mIndex, rangeLength, upperPriceType // ); double lower = bar.FindLowest( mIndex, rangeLength, lowerPriceType // ); // // Validate Upper/Lower ... result = NotEmptyZero(upper) && NotEmptyZero(lower) && upper > lower; if (!result) { return result; } // // Validate Confluence ... XOHCL tmpBar; bool has = false; int tmpCount = 0; double tmpPrice = EMPTY_VALUE; for (int i = bar.Index() + 1; i < bar.Index() + loopback; i++) { // has = tmpBar.Init(bar.symbol, bar.period, i); if (!has) { continue; } // tmpPrice = IsXBullish(forDir) ? tmpBar.GetPrice(upperPriceType) : tmpBar.GetPrice(lowerPriceType); has = NotEmptyZero(tmpPrice) && (IsXBullish(forDir) ? tmpPrice < upper : tmpPrice > lower); if (!has) { // tmpBar.Clean(); // result = false; break; } // // Counting retests ... has = IsXBullish(forDir) ? tmpPrice > lower : tmpPrice > upper; if (has) { tmpCount++; } // tmpBar.Clean(); } // // Validating Retests ... if (result && retests > 0) { // result = result && tmpCount >= retests; } // if (!result) { return result; } // result = confluence.Init( bar.symbol, bar.period, upper, lower, GetBarTime(bar.symbol, bar.period, bar.Index() + loopback + 1), bar.time, forDir, "XConfluence", NULL // At ... ); // return result; } // // Detectors ... /** * Check Specified Bar is Peak or Vale ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param validationLength: int, Validation Length ... * * @return ( bool ) */ bool IsPV( XOHCL &bar, ENUM_X_DIRECTION &dir, int validationLength = 7, ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, // ENUM_X_PRICE valePriceType = X_PRICE_LOW // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalize ... validationLength = NormalizeInt(validationLength, 2); // // Validate ... result = bar.IsValid() && IsXValid(peakPriceType) && IsXValid(valePriceType); if (!result) { return result; } // int valeIndex = -1; double vale = bar.FindLowest( valeIndex, validationLength, valePriceType // ); double barVale = bar.GetPrice(valePriceType); bool isVale = NotEmptyZero(vale) && NotEmptyZero(barVale) && IsValidIndex(valeIndex) && vale >= barVale; // int peakIndex = -1; double peak = bar.FindHighest( peakIndex, validationLength, peakPriceType // ); double barPeak = bar.GetPrice(peakPriceType); bool isPeak = NotEmptyZero(peak) && NotEmptyZero(barPeak) && IsValidIndex(peakIndex) && peak <= barPeak; // result = (isVale && !isPeak) || (isPeak && !isVale); if (result) { // dir = isVale ? X_DIRECTION_BULLISH : isPeak ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... // return result; } /** * Check Specified Bar is Momentum Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param requiredBars: int, bar range for approve Momentum ... * @param approvedMultiplier: double, a Multipler for approve Momentum ... * * @return ( bool ) */ bool IsMomentumBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int requiredBars = 3, double approvedMultiplier = 2 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalizing ... requiredBars = NormalizeInt(requiredBars, 3, 10); approvedMultiplier = NormalizeDouble(approvedMultiplier, 2, 5); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Calculate Requirements ... // XOHCL iBar; bool has = false; double rangeBody = 0; int start = bar.Index() + 1; int end = start + requiredBars; for (int i = start; i < end; i++) { // // Initialized Bar ... has = iBar.Init( bar.symbol, bar.period, i // ); // // Summarize Body Sizes ... if (has) { rangeBody += iBar.GetBody(); } // iBar.Clean(); } // // Calculate Body Approvement ... result = bar.GetBody() >= (approvedMultiplier * rangeBody); if (!result) { return result; } // // Check Direction ... dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... iBar.Clean(); // return result; } /** * Check Specified Bar is Engulfed Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsEngulfedBar( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Calculate Requirements ... // XOHCL iBar; result = bar.GetPreviousBar(iBar); if (!result) { // iBar.Clean(); return result; } // // Check Prev Bar Must Inside Bar ... result = bar.GetUp() > iBar.GetUp() && bar.GetDown() < iBar.GetDown(); if (!result) { // iBar.Clean(); return result; } // // Check Directions ... bool isBullish = iBar.IsBearish() && bar.IsBullish(); bool isBearish = iBar.IsBullish() && bar.IsBearish(); result = isBullish || isBearish; if (!result) { // iBar.Clean(); return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... iBar.Clean(); // return result; } /** * Check Specified Bar is True Gapped Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param approvedPointMultiplier: double, Gap Validation Multiplier in Point ... * * @return ( bool ) */ bool IsTrueGapedBar( XOHCL &bar, ENUM_X_DIRECTION &dir, double approvedPointMultiplier = 1 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalizing ... approvedPointMultiplier = NormalizeDouble(approvedPointMultiplier, 1, 100); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Calculate Requirements ... // XOHCL iBar; result = bar.GetPreviousBar(iBar); if (!result) { // iBar.Clean(); return result; } // // Check Directions ... bool isBullish = iBar.IsBullish() && bar.IsBullish(); bool isBearish = iBar.IsBearish() && bar.IsBearish(); result = isBullish || isBearish; if (!result) { // iBar.Clean(); return result; } // double point = GetPoints(bar.symbol); double approvedGapSize = approvedPointMultiplier * point; // // Check Gap Exists ... result = isBullish ? bar.low > iBar.high : iBar.low > bar.high; if (!result) { // iBar.Clean(); return result; } // // Validate Gap Size ... double gapSize = isBullish ? bar.low - iBar.high : iBar.low - bar.high; result = gapSize >= approvedGapSize; if (!result) { // iBar.Clean(); return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... iBar.Clean(); // return result; } /** * Check Specified Bar is Pinned Bar or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param shadowApprovedMultiplier: double, Shadow Size Approve Multiplier ... * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... * @param forceDirection: bool, Apply Force Bar Type ... * * @return ( bool ) */ bool IsPinnedBar( XOHCL &bar, ENUM_X_DIRECTION &dir, double shadowApprovedMultiplier = 3, double minimumPinBarRangeMultiplier = 4, bool forceDirection = false // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalizing ... shadowApprovedMultiplier = NormalizeDouble(shadowApprovedMultiplier, 2, 5); minimumPinBarRangeMultiplier = NormalizeDouble(minimumPinBarRangeMultiplier, 2, 100); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Calculate Requirements ... double body = bar.GetBody(); double lowShadow = bar.GetLowShadow(); double highShadow = bar.GetHighShadow(); // // Check Directions ... bool isBullish = lowShadow > body && lowShadow > highShadow && lowShadow >= (body * shadowApprovedMultiplier); bool isBearish = highShadow > body && highShadow > lowShadow && highShadow > (body * shadowApprovedMultiplier); result = isBullish || isBearish; if (!result) { return result; } // // Checking Force Bar Type ... if (forceDirection) { // result = isBullish ? bar.IsBullish() : bar.IsBearish(); } if (!result) { return result; } // // Check Range Validation ... double point = GetPoints(bar.symbol); double approvedRange = minimumPinBarRangeMultiplier * point; result = bar.GetRange() >= approvedRange; if (!result) { return result; } // // Setting Direction ... dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // result = HasDirection(dir); // return result; } /** * Check Specified Bar has Star Pattern or not ... * Morning Star => Bullish * Evening Star => Bearish * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsStarPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Get Requirements ... XOHCL pBar, p2Bar; result = bar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // // Check Directions ... bool isBullish = bar.IsBullish() && p2Bar.IsBearish(); bool isBearish = bar.IsBearish() && p2Bar.IsBullish(); result = isBullish || isBearish; if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // // Checking Gap Exists Between Bars ... result = isBullish ? p2Bar.GetDown() > pBar.GetUp() && pBar.GetUp() < bar.GetDown() : p2Bar.GetUp() < pBar.GetDown() && pBar.GetDown() > bar.GetUp(); if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // // Check Bar Close Validation ... double barClosedApprovedPrice = p2Bar.GetDown() + ((p2Bar.GetUp() - p2Bar.GetDown()) / 2); result = isBullish ? bar.close > barClosedApprovedPrice : bar.close < barClosedApprovedPrice; if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // // Validating PBar Body and Shadow ... double body = pBar.GetBody(); double lowShadow = pBar.GetLowShadow(); double highShadow = pBar.GetHighShadow(); result = body < bar.GetBody() && body < p2Bar.GetBody() && (isBullish ? lowShadow > body && lowShadow > highShadow : highShadow > body && highShadow > lowShadow); if (!result) { // pBar.Clean(); p2Bar.Clean(); // return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... pBar.Clean(); p2Bar.Clean(); // return result; } /** * Check Specified Bar has Pirecing Pattern or not ... * Piercing => Bullish * Dark Cloud Cover => Bearish * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsPiercingPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // // Check Directions ... bool isBullish = bar.IsBullish() && pBar.IsBearish(); bool isBearish = bar.IsBearish() && pBar.IsBullish(); result = isBullish || isBearish; if (!result) { // pBar.Clean(); return result; } // // Check Bar Close ... double barCloseApprovedPrice = pBar.GetDown() + ((pBar.GetUp() - pBar.GetDown()) / 2); result = isBullish ? bar.close > barCloseApprovedPrice : bar.close < barCloseApprovedPrice; if (!result) { // pBar.Clean(); return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... pBar.Clean(); // return result; } /** * Check Specified Bar has Rising Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * * @return ( bool ) */ bool IsRisingPattern( XOHCL &bar, ENUM_X_DIRECTION &dir // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Reading Required Bars ... XOHCL iBar; XOHCL bars[]; bool has = false; int start = bar.Index(); int end = start + 5; for (int i = start; i < end; i++) { // // Initialized Bar ... has = iBar.Init( bar.symbol, bar.period, i // ); if (has) { // AddRef( iBar, bars // ); } // iBar.Clean(); } result = ArraySize(bars) == 5; if (!result) { // iBar.Clean(); SpecifiedClean(bars); // return result; } // // Check Directions ... bool isBullish = bars[0].IsBullish() && bars[4].IsBullish() && bars[1].IsBearish() && bars[2].IsBearish() && bars[3].IsBearish(); bool isBearish = bars[0].IsBearish() && bars[4].IsBearish() && bars[1].IsBullish() && bars[2].IsBullish() && bars[3].IsBullish(); result = isBullish || isBearish; if (!result) { // iBar.Clean(); SpecifiedClean(bars); // return result; } // // Check Range Validation ... double upper = bars[4].GetUp(); double lower = bars[4].GetDown(); // double max = MathMax(bars[1].GetUp(), bars[2].GetUp()); max = MathMax(max, bars[3].GetUp()); // double min = MathMin(bars[1].GetDown(), bars[2].GetDown()); min = MathMin(min, bars[3].GetDown()); // result = max < upper && min > lower && (isBullish ? bars[0].close > bars[4].GetUp() : bars[0].close < bars[4].GetDown()); if (!result) { // iBar.Clean(); SpecifiedClean(bars); // return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... iBar.Clean(); SpecifiedClean(bars); // return result; } /** * Check Specified Bar has Flag Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param swingBar: XOHCL, Detected Swing Bar ... * @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ... * * @return ( bool ) */ bool IsFlagPattern( XOHCL &bar, ENUM_X_DIRECTION &dir, XOHCL &swingBar, int minimumPullbackBars = 3 // ) { // bool result = false; // // Prepare ... swingBar.Clean(); CleanDirection(dir); // // Normalizing ... minimumPullbackBars = NormalizeInt(minimumPullbackBars, 3, 10); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Reading Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { // pBar.Clean(); return result; } // // Check Directions ... bool isBullish = bar.IsBullish() && bar.close > pBar.GetUp(); bool isBearish = bar.IsBearish() && bar.close < pBar.GetDown(); result = isBullish || isBearish; if (!result) { // pBar.Clean(); return result; } // // Detect Swing Bar ... ENUM_X_SWING_TYPE swingType = isBullish ? X_SWING_HIGH : X_SWING_LOW; result = result && IsXValid(swingType) && bar.FindNextSwingBar( swingType, swingBar, minimumPullbackBars // ) && (isBullish ? swingBar.IsBullish() && swingBar.high > pBar.high : swingBar.IsBearish() && swingBar.low < pBar.low); if (!result) { // pBar.Clean(); swingBar.Clean(); // return result; } // dir = bar.GetDirection(); // // Get Result ... result = HasDirection(dir); // // Cleanup Resources ... pBar.Clean(); if (!result) { swingBar.Clean(); } // return result; } /** * Check Specified Bar has SignalKey Bar Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param shadowApprovedMultiplier: double, Shadow Size Approve Multiplier ... * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... * @param forceDirection: bool, Apply Force Bar Type ... * * @return ( bool ) */ bool IsSignalKeyBarPattern( XOHCL &bar, ENUM_X_DIRECTION &dir, double shadowApprovedMultiplier = 3, double minimumPinBarRangeMultiplier = 4, bool forceDirection = false // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Get Requirements ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Chck Previous Bar must Pinned ... result = IsPinnedBar( pBar, dir, shadowApprovedMultiplier, minimumPinBarRangeMultiplier, forceDirection // ); if (!result) { // pBar.Clean(); return result; } // // Check Direction ... bool isBullish = bar.IsBullish() && IsSpecifiedBullish(dir) && bar.close > pBar.high; bool isBearish = bar.IsBearish() && IsSpecifiedBearish(dir) && bar.close < pBar.low; result = isBullish || isBearish; if (!result) { // pBar.Clean(); return result; } // dir = bar.GetDirection(); // result = HasDirection(dir); // // Cleanup Resources ... pBar.Clean(); // return result; } /** * Check Specified Bar has Pullback Bar Pattern or not ... * * @param bar: XOHCL, Specified Bar ... * @param zone: XBoxZone, refrence to hold detected zone ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param pullbackLength: int, min required indirectional bars to confirm pullback ... * @param forceBreak: bool, force pullback bar breaks peak or vale of Zone ... * * @return ( bool ) */ bool IsPullbackPattern( XOHCL &bar, XBoxZone &zone, ENUM_X_DIRECTION &dir, int pullbackLength = 2, bool forceBreak = false // ) { // bool result = false; // // Prepare ... zone.Clean(); CleanDirection(dir); // // Normalize ... pullbackLength = NormalizeInt(pullbackLength, 2); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // First Bar Direction ... dir = bar.GetDirection(); result = HasDirection(dir); if (!result) { return result; } // // Loop through Pullback Length ... XOHCL iBar; datetime from = NULL; double max = EMPTY_VALUE; double min = EMPTY_VALUE; int start = bar.Index() + 1; int end = start + pullbackLength; for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... iBar.Clean(); result = bar.BarAt(i, iBar) && iBar.GetDirection() == Opposit(dir); if (!result) { break; } // // Calculate Max and Min ... max = !NotEmptyZero(max) ? iBar.high : MathMax(max, iBar.high); min = !NotEmptyZero(min) ? iBar.low : MathMin(min, iBar.low); from = iBar.time; } // // Apply Force Break ... if (result && forceBreak) { // result = result && NotEmptyZero(min) && NotEmptyZero(max) && (IsXBullish(dir) ? bar.close > max : bar.close < min); } // // Prepare Zone ... if (result) { // ToBox( bar, zone, dir, ToXString(X_BAR_PATTERN_PULLBACK) // ); zone.upper = max; zone.lower = min; zone.from = from; zone.at = bar.time; zone.to = bar.time; // result = zone.IsValid(); } // // Cleanup ... if (!result) { // zone.Clean(); CleanDirection(dir); } iBar.Clean(); // return result; } /** * Check Market Has Consolidation Pattern or not ... * * @param bar: XOHCL, reference to Specified Bar ... * @param zone: XBoxZone, refrence to hold detected zone ... * @param dir: ENUM_X_DIRECTION, reference to holds Detected Order Flow Direction ... * @param validationLength: int, Validation Length ... * @param breakPriceType: ENUM_X_PRICE, Specified Price Type to Breake Consolidation ... * @param upperPriceType: ENUM_X_PRICE, Specified Price Type to Detected Upper of Consolidation ... * @param lowerPriceType: ENUM_X_PRICE, Specified Price Type to Detected Lower of Consolidation ... * * @return ( bool ) */ bool IsConsolidationPattern( XOHCL &bar, XBoxZone &zone, ENUM_X_DIRECTION &dir, int validationLength = 5, ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE, ENUM_X_PRICE upperPriceType = X_PRICE_HIGH, ENUM_X_PRICE lowerPriceType = X_PRICE_LOW // ) { // // Descriptions: // =============== // Consolidation Zones Happens by Highest High and Lowest Low // of Specified Range which Breakes From one Side ... // // bool result = false; // // Prepare ... zone.Clean(); CleanDirection(dir); // // Normalize ... validationLength = NormalizeInt(validationLength, 3); // // Validate ... result = bar.IsValid() && IsXValid(lowerPriceType) && IsXValid(upperPriceType) && IsXValid(breakPriceType); if (!result) { return result; } // // Define Requirements ... XOHCL iBar; bool has = false; datetime to = NULL; datetime from = NULL; double iLow = EMPTY_VALUE; bool hasLowShadow = false; double lower = EMPTY_VALUE; double upper = EMPTY_VALUE; double iHigh = EMPTY_VALUE; bool hasHighShadow = false; double iPrice = EMPTY_VALUE; bool isLowerBreaked = false; bool isUpperBreaked = false; // // Loop Through Bars ... int barIndex = bar.Index(); int idx = barIndex; bool canLookup = IsValidIndex(idx); while (canLookup) { // // Initialize Indexed Bar ... idx++; iBar.Clean(); result = bar.BarAt(idx, iBar); if (!result) { break; } // // Update Time ... if (idx == barIndex + 1) { to = iBar.time; } // // Extract Low and High Price ... iLow = iBar.GetPrice(lowerPriceType); iHigh = iBar.GetPrice(upperPriceType); result = NotEmptyZero(iLow) && NotEmptyZero(iHigh); if (!result) { break; } // // Check Bar Has Low/High Shadow ... hasLowShadow = iBar.GetLowShadow() > iBar.GetHighShadow(); hasHighShadow = iBar.GetHighShadow() > iBar.GetLowShadow(); // // Update Range Lower and Upper based on Shadows ... // // Lower ... if (hasLowShadow) { // // Check Can Update ... has = !NotEmptyZero(lower) ? true : iLow < lower; if (has) { lower = iLow; } } // // Upper ... if (hasHighShadow) { // // Check Can Update ... has = !NotEmptyZero(upper) ? true : iHigh > upper; if (has) { upper = iHigh; } } // // Check Price Breakes ... iPrice = iBar.GetPrice(breakPriceType); result = NotEmptyZero(iPrice); if (!result) { break; } // // Check Upper/Lower breakes ... isLowerBreaked = iPrice < lower; isUpperBreaked = iPrice > upper; // canLookup = (!isLowerBreaked && !isUpperBreaked); if (!canLookup) { break; } // from = iBar.time; } // // Validate Calculations ... result = // IsXValid(to) && IsXValid(from) && from < to && // NotEmptyZero(lower) && NotEmptyZero(upper) && upper > lower // ; // // Validate To Edge Breakes ... if (result) { // iPrice = bar.GetPrice(breakPriceType); result = NotEmptyZero(iPrice); // // Validate To Edge Breakes ... if (result) { // isUpperBreaked = iPrice > upper; isLowerBreaked = iPrice < lower; // // Validate To Break ... result = isUpperBreaked || isLowerBreaked; } // // Prepare Direction ... if (result) { // dir = isUpperBreaked ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Validate Direction ... result = HasDirection(dir); } // // Prepare Zone ... if (result) { // zone.to = to; zone.dir = dir; zone.from = from; zone.at = bar.time; zone.upper = upper; zone.lower = lower; zone.symbol = bar.symbol; zone.period = bar.period; zone.type = ToXString(X_BAR_PATTERN_CONSOLIDATION); // // Validate Zone ... result = zone.IsValid(); // // Validate Zone Length ... if (result) { result = zone.FromIndex() - zone.ToIndex() >= validationLength; } } // // Cleanup ... if (!result) { // zone.Clean(); CleanDirection(dir); } iBar.Clean(); // return result; } bool HasCandlestickDirection( XOHCL &bar, ENUM_X_DIRECTION forDir, bool checkStarPattern = true, bool checkPinBarPattern = true, bool checkPiercingPattern = true, bool checkEngulfedPattern = true, bool checkMomentumPattern = true, bool checkSignalKeyBarPattern = true // ) { // bool result = false; // // Validate ... result = bar.IsValid() && HasDirection(forDir); if (!result) { return result; } // ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; // // Star ... bool isStarPattern = false; if (checkStarPattern) { // isStarPattern = IsStarPattern(bar, tmpDir) && tmpDir == forDir; } // bool isPiercingPattern = false; if (checkPiercingPattern) { // isPiercingPattern = IsPiercingPattern(bar, tmpDir) && tmpDir == forDir; } // // Engulfed ... bool isEngulfedPattern = false; if (checkEngulfedPattern) { // isEngulfedPattern = IsEngulfedBar(bar, tmpDir) && tmpDir == forDir; } // // PinBar ... bool isPinBarPattern = true; if (checkPinBarPattern) { // isPinBarPattern = IsPinnedBar(bar, tmpDir) && tmpDir == forDir; } // // Signal Key Bar ... bool isSignalKeyBarPattern = false; if (checkSignalKeyBarPattern) { // isSignalKeyBarPattern = IsSignalKeyBarPattern(bar, tmpDir) && tmpDir == forDir; } // // Momentum Bar ... bool isMomentumBarPattern = false; if (checkMomentumPattern) { // isMomentumBarPattern = IsMomentumBar(bar, tmpDir) && tmpDir == forDir; } // result = isStarPattern || isPinBarPattern || isPiercingPattern || isEngulfedPattern || isMomentumBarPattern || isSignalKeyBarPattern; // return result; } /** * Detect Order Flow ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dir: ENUM_X_DIRECTION, reference to holds Detected Order Flow Direction ... * @param orderFlow: XBoxZone, collection reference to holds Detected Order Flow ... * @param orderFlowValidation: int, number of sequential Zones for Validate Order Flow ... * @param containsOBs: bool, Specified to Use Order Blocks in Order Flow Detection ... * @param containsFVGs: bool, Specified to Use Fair Value Gaps in Order Flow Detection ... * @param containsSupportResistances: bool, Specified to Use Support and Resistances in Order Flow Detection ... * @param zonesLoopback: int, Zone Detection Loopback ... * @param zonesValidationLength: int, Zone Validation Length ... * @param loopback: int, Max Allowed Loopback Bars for Collecting ... * * @return ( bool ) */ bool HasOrderFlow( XOHCL &bar, ENUM_X_DIRECTION &dir, XBoxZone &orderFlow[], int orderFlowValidation = 2, bool containsOBs = false, bool containsFVGs = true, bool containsSupportResistances = false, int zonesLoopback = 5, int zonesValidationLength = 21, int loopback = 100 // ) { // bool result = false; // // Prepare ... XClean(orderFlow); CleanDirection(dir); int maxRequiredZone = 0; // // Normalize ... loopback = NormalizeInt(loopback, 10); zonesLoopback = NormalizeInt(zonesLoopback, 3); maxRequiredZone = NormalizeInt(maxRequiredZone, 0); orderFlowValidation = NormalizeInt(orderFlowValidation, 1); zonesValidationLength = NormalizeInt(zonesValidationLength, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Do ... // // Collectiong Zones ... XBoxZone tmp; XBoxZone tmps[]; XBoxZone _zones[]; XBoxZone bullishZones[]; XBoxZone bearishZones[]; int bullishZonesCount = 0; int bearishZonesCount = 0; // // Order Blocks ... if (containsOBs) { // XClean(tmps); CollectOBs(bar, tmps, zonesLoopback, maxRequiredZone, loopback); FillNotExists(_zones, tmps); } // // Fair Value Gaps ... if (containsFVGs) { // XClean(tmps); CollectFVGs(bar, tmps, zonesLoopback, maxRequiredZone, loopback); FillNotExists(_zones, tmps); } // // Support and Resistances ... if (containsSupportResistances) { // XClean(tmps); CollectZones(bar, tmps, zonesLoopback, maxRequiredZone, loopback); FillNotExists(_zones, tmps); } // // Validate Zones ... result = HasChild(_zones); // // Extract Only Validated Zones ... if (result) { // ValidateBoxes( _zones, bar.Index() // Bars Length ... ); // UpdateToTime(_zones, bar.time); RemoveBreakedZones(_zones, X_PRICE_CLOSE); // result = HasChild(_zones); } // // Separate Zones Direction ... if (result) { // bullishZonesCount = ExtractByDirection(bullishZones, _zones, X_DIRECTION_BULLISH); bearishZonesCount = ExtractByDirection(bearishZones, _zones, X_DIRECTION_BEARISH); // result = IsValidSize(bullishZonesCount) || IsValidSize(bearishZonesCount); } // // Looking for Sequences of Zones ... if (result) { // int idx = -1; bool has = false; XBoxZone bullOrderFlow[]; XBoxZone bearOrderFlow[]; // // Bullish OrderFlow ... // // Sorting ... Copy(bullishZones, bullOrderFlow); Sort( bullOrderFlow, X_SORT_BY_DATE, X_DIRECTION_BEARISH, orderFlowValidation + 1 // ); bool hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation; if (hasBullishOrderFlow) { // // Validate Order Flow ... Copy(bullOrderFlow, tmps); XClean(bullOrderFlow); while (HasChild(tmps)) { // tmp.Clean(); tmp = tmps[0]; ArrayRemove(tmps, 0, 1); // idx = GetHighest(tmps); has = !IsValidIndex(idx) ? true : tmps[idx].lower < tmp.lower; if (has) { AddIfNotExists(tmp, bullOrderFlow); } } // hasBullishOrderFlow = ArraySize(bullOrderFlow) >= orderFlowValidation; } // // Bearish OrderFlow ... // // Sorting ... Copy(bearishZones, bearOrderFlow); Sort( bearOrderFlow, X_SORT_BY_DATE, X_DIRECTION_BULLISH, orderFlowValidation + 1 // ); bool hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation; if (hasBearishOrderFlow) { // // Validate Order Flow ... Copy(bearOrderFlow, tmps); XClean(bearOrderFlow); while (HasChild(tmps)) { // tmp.Clean(); tmp = tmps[0]; ArrayRemove(tmps, 0, 1); // idx = GetLowest(tmps); has = !IsValidIndex(idx) ? true : tmps[idx].upper > tmp.upper; if (has) { AddIfNotExists(tmp, bearOrderFlow); } } // hasBearishOrderFlow = ArraySize(bearOrderFlow) >= orderFlowValidation; } // result = hasBullishOrderFlow || hasBearishOrderFlow; // // Validate Order Flows ... if (result) { // has = (hasBullishOrderFlow && !hasBearishOrderFlow) || (hasBearishOrderFlow && !hasBullishOrderFlow); // // When only Have One Direction ... if (has) { // if (hasBullishOrderFlow) { // dir = X_DIRECTION_BULLISH; Copy(bullOrderFlow, orderFlow); } else if (hasBearishOrderFlow) { // dir = X_DIRECTION_BEARISH; Copy(bearOrderFlow, orderFlow); } } // // When Two Direction Exists ... else { // // Retrieve Oldest Of Bullish / Bearish ... int oldestBullIDX = GetOldest(bullOrderFlow); int oldestBearIDX = GetOldest(bearOrderFlow); result = IsValidIndex(oldestBullIDX) && IsValidIndex(oldestBearIDX); if (result) { // dir = bullOrderFlow[oldestBullIDX].from > bearOrderFlow[oldestBearIDX].from ? X_DIRECTION_BULLISH : bearOrderFlow[oldestBearIDX].from > bullOrderFlow[oldestBullIDX].from ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // result = HasDirection(dir); if (result) { // if (IsXBullish(dir)) { Copy(bullOrderFlow, orderFlow); } else if (IsXBearish(dir)) { Copy(bearOrderFlow, orderFlow); } } } } // XClean(bullOrderFlow); XClean(bearOrderFlow); // result = HasChild(orderFlow) && HasDirection(dir); } // // Validate Price ... if (result) { // int idx = -1; if (IsXBullish(dir)) { // idx = GetHighest(orderFlow); result = IsValidIndex(idx) && bar.low > orderFlow[idx].upper; } else { // idx = GetLowest(orderFlow); result = IsValidIndex(idx) && bar.high < orderFlow[idx].lower; } } // // Update To Time of Order Flow ... if (result) { UpdateToTime(orderFlow, bar.time); } // // Cleanup ... if (!result) { // XClean(orderFlow); CleanDirection(dir); } tmp.Clean(); XClean(tmps); XClean(_zones); XClean(bullishZones); XClean(bearishZones); // return result; } // // FVG ... /** * Check For FVG Exists in Specified Loopback Period ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param fvg: XBoxZone, reference for Holding FVG ... * @param maxLoopback: int, Max Allowed Loopback to Lookup FVG ... * * @return ( bool ) */ bool HasFVG( XOHCL &bar, ENUM_X_DIRECTION &dir, XBoxZone &fvg, int maxLoopback = 5 // ) { // bool result = false; // // Prepare ... fvg.Clean(); CleanDirection(dir); // // Normalize ... maxLoopback = NormalizeInt(maxLoopback, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL iBar; bool has = false; int start = bar.Index(); int end = start + maxLoopback; for (int i = start; i < end; i++) { // // Initialize iBar ... has = iBar.Init( bar.symbol, bar.period, i // ); if (!has) { continue; } // // Check iBar is FVG or not ... has = barAnalyser.IsFVG( iBar, fvg, true // Force Bar Type ... ); if (!has) { // fvg.Clean(); iBar.Clean(); CleanDirection(dir); // continue; } // iBar.Clean(); dir = fvg.dir; // break; } // // Check FVG Exists ... result = fvg.IsValid(); // // Check Direction Exists ... result = result && HasDirection(dir); // // Cleanup Resources ... if (!result) { // fvg.Clean(); CleanDirection(dir); } iBar.Clean(); // return result; } // // OB ... /** * Check For OB Exists in Specified Loopback Period ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param ob: XBoxZone, reference for Holding OB ... * @param maxLoopback: int, Max Allowed Loopback to Lookup OB ... * * @return ( bool ) */ bool HasOB( XOHCL &bar, ENUM_X_DIRECTION &dir, XBoxZone &ob, int maxLoopback = 5 // ) { // bool result = false; // // Prepare ... ob.Clean(); CleanDirection(dir); // // Normalize ... maxLoopback = NormalizeInt(maxLoopback, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL iBar; bool has = false; int start = bar.Index(); int end = start + maxLoopback; for (int i = start; i < end; i++) { // // Initialize iBar ... has = iBar.Init( bar.symbol, bar.period, i // ); if (!has) { continue; } // // Check iBar is OB or not ... has = barAnalyser.IsOB( iBar, ob, true, // Force FVG Bar Type ... true // Force OB First Two Bar InDirection ... ); if (!has) { // ob.Clean(); iBar.Clean(); CleanDirection(dir); // continue; } // iBar.Clean(); dir = ob.dir; // break; } // // Check OB Exists ... result = ob.IsValid(); // // Check Direction Exists ... result = result && HasDirection(dir); // // Cleanup Resources ... if (!result) { // ob.Clean(); CleanDirection(dir); } iBar.Clean(); // return result; } // // Complex ... /** * Check Double Pinned Bar ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... * @param shadowApprovedMultiplier: double, Shadow Size Approve Multiplier ... * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... * @param forceDirection: bool, Apply Force Bar Type ... * @param loopback: int, Max Allowed Detecting Loopback lenght ... * * @return ( bool ) */ bool IsDoublePinned( XOHCL &bar, ENUM_X_DIRECTION &dir, double shadowApprovedMultiplier = 3, double minimumPinBarRangeMultiplier = 4, bool forceDirection = false, int loopback = 5 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalize ... loopback = NormalizeInt(loopback, 1); shadowApprovedMultiplier = NormalizeDouble(shadowApprovedMultiplier, 2, 5); minimumPinBarRangeMultiplier = NormalizeDouble(minimumPinBarRangeMultiplier, 2, 100); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Do ... // // Current Bar Must be a Pinned Bar ... result = IsPinnedBar( bar, dir, shadowApprovedMultiplier, minimumPinBarRangeMultiplier, forceDirection // ); if (!result) { // CleanDirection(dir); // return result; } // XOHCL iBar; ENUM_X_DIRECTION iDir; int start = bar.Index() + 1; int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); result = bar.BarAt(i, iBar); result = result && IsPinnedBar( iBar, iDir, shadowApprovedMultiplier, minimumPinBarRangeMultiplier, forceDirection // ); result = result && iDir == dir; if (result) { break; } } // // Cleanup ... if (!result) { CleanDirection(dir); } iBar.Clean(); CleanDirection(iDir); // return result; } /** * Check Double Engulfed Bar ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... * @param loopback: int, Max Allowed Detecting Loopback lenght ... * * @return ( bool ) */ bool IsDoubleEngulfed( XOHCL &bar, ENUM_X_DIRECTION &dir, int loopback = 5 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalize ... loopback = NormalizeInt(loopback, 1); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Do ... // // Current Bar Must be a Pinned Bar ... result = IsEngulfedBar( bar, dir // ); if (!result) { // CleanDirection(dir); // return result; } // XOHCL iBar; ENUM_X_DIRECTION iDir; int start = bar.Index() + 1; int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); result = bar.BarAt(i, iBar); result = result && IsEngulfedBar( iBar, iDir // ); result = result && iDir == dir; if (result) { break; } } // // Cleanup ... if (!result) { CleanDirection(dir); } iBar.Clean(); CleanDirection(iDir); // return result; } /** * Check Double Momentum Bar ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dir: ENUM_X_DIRECTION, reference to holds Pattern Direction ... * @param requiredBars: int, bar range for approve Momentum ... * @param approvedMultiplier: double, a Multipler for approve Momentum ... * @param loopback: int, Max Allowed Detecting Loopback lenght ... * * @return ( bool ) */ bool IsDoubleMomentum( XOHCL &bar, ENUM_X_DIRECTION &dir, int requiredBars = 3, double approvedMultiplier = 2, int loopback = 5 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); // // Normalize ... loopback = NormalizeInt(loopback, 1); requiredBars = NormalizeInt(requiredBars, 3, 10); approvedMultiplier = NormalizeDouble(approvedMultiplier, 2, 5); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Do ... // // Current Bar Must be a Pinned Bar ... result = IsMomentumBar( bar, dir, requiredBars, approvedMultiplier // ); if (!result) { // CleanDirection(dir); // return result; } // XOHCL iBar; ENUM_X_DIRECTION iDir; int start = bar.Index() + 1; int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); result = bar.BarAt(i, iBar); result = result && IsMomentumBar( iBar, iDir, requiredBars, approvedMultiplier // ); result = result && iDir == dir; if (result) { break; } } // // Cleanup ... if (!result) { CleanDirection(dir); } iBar.Clean(); CleanDirection(iDir); // return result; } /** * Check Has Double Patterns ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dir: ENUM_X_DIRECTION, reference to holds Specified Patterns ... * @param barPatterns: XPatternAnalysis, reference to Provides Bar's Pattern Analysis ... * @param pBarPatterns: XPatternAnalysis, reference to Provides Previous Bar's Pattern Analysis ... * @param allowedPatterns: ENUM_X_BAR_PATTERN, collection to Provide Allowed Bar Patterns for Detection ... * @param config: XPatternAnalysisConfig, Provides Patterns Detection Config ... * @param loopback: int, Max Allowed Loopback for Detection ... * @param forDir: ENUM_X_DIRECTION, Specified Patterns Detection Direction ... * * @return ( bool ) */ bool HasDoublePatterns( XOHCL &bar, ENUM_X_DIRECTION &dir, XPatternAnalysis &barPatterns, XPatternAnalysis &pBarPatterns, ENUM_X_BAR_PATTERN &allowedPatterns[], XPatternAnalysisConfig &config, int loopback = 5, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // // Prepare ... barPatterns.Clean(); CleanDirection(dir); pBarPatterns.Clean(); XPatternAnalysisConfig iConfig = config; // // Normalize ... loopback = NormalizeInt(loopback, 2); // // Validate ... result = bar.IsValid() && HasChild(allowedPatterns); if (!result) { return result; } // // Prepare Config ... iConfig.CleanPatterns(); if (HasChild(allowedPatterns)) { // for (int i = 0; i < ArraySize(allowedPatterns); i++) { iConfig.AddPattern(allowedPatterns[i]); } } // // Detect Bar Patterns ... result = AnalyseBarPatterns(bar, barPatterns, config); if (!result) { // CleanDirection(dir); barPatterns.Clean(); pBarPatterns.Clean(); // return result; } // // Check Direction ... int bullishCount = barPatterns.Count(X_DIRECTION_BULLISH); int bearishCount = barPatterns.Count(X_DIRECTION_BEARISH); dir = bullishCount > bearishCount ? X_DIRECTION_BULLISH : bearishCount > bullishCount ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; result = HasDirection(dir); // // Check for Dir ... if (HasDirection(forDir)) { // result = result && dir == forDir; } // // Looping Back ... if (result) { // XOHCL iBar; ENUM_X_DIRECTION iDir; int start = bar.Index() + 1; int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); pBarPatterns.Clean(); result = bar.BarAt(i, iBar); result = result && AnalyseBarPatterns(iBar, pBarPatterns, iConfig); if (!result) { continue; } // bullishCount = pBarPatterns.Count(X_DIRECTION_BULLISH); bearishCount = pBarPatterns.Count(X_DIRECTION_BEARISH); iDir = bullishCount > bearishCount ? X_DIRECTION_BULLISH : bearishCount > bullishCount ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; result = HasDirection(iDir); result = result && dir == iDir; if (result) { break; } } // iBar.Clean(); CleanDirection(iDir); } // // Cleanup ... if (!result) { // CleanDirection(dir); barPatterns.Clean(); pBarPatterns.Clean(); } iConfig.Clean(); // return result; } /** * Count Same Bars ... * * @param bar: XOHCL, Specified Bar ... * @param sameBars: XOHCL, collection reference to holds same Bars ... * @param dir: ENUM_X_DIRECTION, refrence to Founded Bars Direction holding ... * @param forDir: ENUM_X_DIRECTION, Specified Looking Bar ... * * @return ( int ) */ int CountSameBars( XOHCL &bar, XOHCL &sameBars[], ENUM_X_DIRECTION &dir, ENUM_X_DIRECTION forDir // ) { // int result = 0; // // Prepare ... XClean(sameBars); // // Validate ... bool has = bar.IsValid(); if (!has) { return result; } // XOHCL tmpBar; ENUM_X_DIRECTION tmpDir = forDir; int idx = bar.Index(); while (has) { // idx++; tmpBar.Clean(); has = bar.BarAt(idx, tmpBar); if (has && !HasDirection(tmpDir)) { tmpDir = tmpBar.GetDirection(); } has = has && tmpBar.GetDirection() == tmpDir; if (!has) { break; } // AddIfNotExists(tmpBar, sameBars); } // result = ArraySize(sameBars); if (IsValidSize(result)) { dir = tmpDir; } // // Cleanup ... tmpBar.Clean(); // return result; } // // Trending ... /** * Check Trend Exists Based on Swings ... * * @param bar: XOHCL, Specified Bar ... * @param dir: ENUM_X_DIRECTION a reference for Direction ... * @param swings: XOHCL Array, Holds Swings ... * @param numberOfSwings: int, Number of Swing Points for Detect Trend ... * @param swingShoulders: int, Swing Shoulders Approvement Length ... * * @return ( bool ) */ bool HasSwingTrend( XOHCL &bar, ENUM_X_DIRECTION &dir, XOHCL &swings[], int numberOfSwings = 3, int swingShoulders = 7 // ) { // bool result = false; // // Prepare ... CleanDirection(dir); SpecifiedClean(swings); // // Normalizing ... numberOfSwings = NormalizeInt(numberOfSwings, 3, 10); swingShoulders = NormalizeInt(swingShoulders, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Check Trend Direction ... XOHCL iSwing; int idx = -1; bool has = false; XOHCL swingLows[]; XOHCL swingHighs[]; int lastSwingLowIndex = bar.Index(); int lastSwingHighIndex = bar.Index(); while (ArraySize(swingLows) < numberOfSwings || ArraySize(swingHighs) < numberOfSwings) { // bool canLookupSwingLow = ArraySize(swingLows) < numberOfSwings; bool canLookupSwingHigh = ArraySize(swingHighs) < numberOfSwings; if (!canLookupSwingLow && !canLookupSwingHigh) { break; } // // Handle Swing Lows ... if (canLookupSwingLow) { // iSwing.Clean(); idx = FindXSwing( X_SWING_LOW, bar.symbol, bar.period, lastSwingLowIndex + 1, swingShoulders // ); has = IsValidIndex(idx); if (has) { // has = iSwing.Init( bar.symbol, bar.period, idx // ); if (has) { // AddRef( iSwing, swingLows // ); // lastSwingLowIndex = idx; } } } // // Handle Swing Highs ... if (canLookupSwingHigh) { // iSwing.Clean(); idx = FindXSwing( X_SWING_HIGH, bar.symbol, bar.period, lastSwingHighIndex + 1, swingShoulders // ); has = IsValidIndex(idx); if (has) { // has = iSwing.Init( bar.symbol, bar.period, idx // ); if (has) { // AddRef( iSwing, swingHighs // ); // lastSwingHighIndex = idx; } } } } // // Check Trend Based On Swings ... // // Check Directions ... // bool isBullish = false; bool isBearish = false; // datetime oldestSwingLow = NULL; datetime oldestSwingHigh = NULL; // // Checking Bullish Trend based on Swing Lows ... int count = ArraySize(swingLows); for (int i = 0; i < count - 1; i++) { // has = swingLows[i].low > swingLows[i + 1].low; isBullish = !isBullish ? has : isBullish && has; if (!isBullish) { break; } // datetime oldeTime = MathMin(swingLows[i].time, swingLows[i + 1].time); oldestSwingLow = !IsSpecifiedValid(oldestSwingLow) ? oldeTime : MathMin(oldestSwingLow, oldeTime); } // // Checking Bearish Trend based on Swing Highs ... count = ArraySize(swingHighs); for (int i = 0; i < count - 1; i++) { // has = swingHighs[i].high < swingHighs[i + 1].high; isBearish = !isBearish ? has : isBearish && has; if (!isBearish) { break; } // datetime oldeTime = MathMin(swingHighs[i].time, swingHighs[i + 1].time); oldestSwingHigh = !IsSpecifiedValid(oldestSwingHigh) ? oldeTime : MathMin(oldestSwingHigh, oldeTime); } // result = isBullish || isBearish; if (!result) { // iSwing.Clean(); SpecifiedClean(swingLows); SpecifiedClean(swingHighs); // return result; } // if (isBullish && isBearish && IsSpecifiedValid(oldestSwingLow) && IsSpecifiedValid(oldestSwingHigh)) { // // Here we Have to Detect Newest Trend or Oldest Trend ... isBullish = oldestSwingLow < oldestSwingHigh; isBearish = oldestSwingHigh < oldestSwingLow; } // result = (isBullish && !isBearish) || (isBearish && !isBullish); if (!result) { // iSwing.Clean(); SpecifiedClean(swingLows); SpecifiedClean(swingHighs); // return result; } // if (isBullish) { // Copy( swingLows, swings // ); // dir = X_DIRECTION_BULLISH; } else { // Copy( swingHighs, swings // ); // dir = X_DIRECTION_BEARISH; } // iSwing.Clean(); SpecifiedClean(swingLows); SpecifiedClean(swingHighs); // return result; } /** * Check Specified Bar Has Support or not ... * * @param bar: XOHCL, Specified Bar ... * @param support: XOHCL, Supported Bar ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool HasSupport( XOHCL &bar, XOHCL &support, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // bool result = false; // // Prepare ... support.Clean(); // // Normalizing ... validationLength = NormalizeInt(validationLength, 7); maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 21, 1500); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Find Support Swing ... int idx = -1; bool has = false; int lookupIDX = bar.Index(); while (!IsValidIndex(idx) && lookupIDX < maxAllowedLoopback) { // // Detect Swing ... idx = FindXSwing( X_SWING_LOW, bar.symbol, bar.period, lookupIDX, validationLength // ); has = IsValidIndex(idx); if (!has) { // lookupIDX++; continue; } // // Retrieve Swing Bar ... has = support.Init( bar.symbol, bar.period, idx // ); if (!has) { // idx = -1; lookupIDX++; support.Clean(); continue; } // // Check Suppor Low Shadow ... has = support.GetDown() < bar.low; if (!has) { // idx = -1; lookupIDX++; support.Clean(); continue; } // if (IsValidIndex(idx)) { break; } } // result = support.IsValid(); // return result; } /** * Check Specified Bar Has Resistance or not ... * * @param bar: XOHCL, Specified Bar ... * @param resistence: XOHCL, Resistanced Bar ... * @param validationLength: int, Validation Length ... * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... * * @return ( bool ) */ bool HasResistance( XOHCL &bar, XOHCL &resistence, int validationLength = 21, int maxAllowedLoopback = 1500 // ) { // bool result = false; // // Prepare ... resistence.Clean(); // // Normalizing ... validationLength = NormalizeInt(validationLength, 7); maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 21, 1500); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Find Support Swing ... int idx = -1; bool has = false; int lookupIDX = bar.Index(); while (!IsValidIndex(idx) && lookupIDX < maxAllowedLoopback) { // // Detect Swing ... idx = FindXSwing( X_SWING_HIGH, bar.symbol, bar.period, lookupIDX, validationLength // ); has = IsValidIndex(idx); if (!has) { // lookupIDX++; continue; } // // Retrieve Swing Bar ... has = resistence.Init( bar.symbol, bar.period, idx // ); if (!has) { // idx = -1; lookupIDX++; resistence.Clean(); continue; } // // Check Resistance High Shadow ... has = resistence.GetUp() > bar.high; if (!has) { // idx = -1; lookupIDX++; resistence.Clean(); continue; } // if (IsValidIndex(idx)) { break; } } // result = resistence.IsValid(); // return result; } /** * Check Specified Bar Has Support or Resistance and Extract them ... * * @param bar: XOHCL, reference to Specified Bar ... * @param support: XBoxZone, reference to holds Detected Support ... * @param resistance: XBoxZone, reference to holds Detected Resistance ... * @param validationLength: int, Specified Validation Length ... * @param loopback: int, Max Allowed Loopback Bars for Detection ... * * @return ( bool ) */ bool HasSupportResistance( XOHCL &bar, XBoxZone &support, XBoxZone &resistance, int validationLength = 7, int loopback = 100 // ) { // bool result = false; // // Prepare ... support.Clean(); resistance.Clean(); // // Normalize ... loopback = NormalizeInt(loopback, 50); validationLength = NormalizeInt(validationLength, 3); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL iZBar; // // Support ... iZBar.Clean(); bool hasSupport = HasSupport( bar, iZBar, validationLength, loopback // ); if (hasSupport) { // hasSupport = ToSupportBox( iZBar, support, bar.time // ); } // // Resistance ... iZBar.Clean(); bool hasResistance = HasResistance( bar, iZBar, validationLength, loopback // ); if (hasResistance) { // hasResistance = ToResistanceBox( iZBar, resistance, bar.time // ); } // // Summarize Result ... result = hasSupport || hasResistance; // // Cleanup ... iZBar.Clean(); // return result; } // // Analysers ... /** * Analyse Specified Bar ... * * @param bar: XOHCL, reference to Specified Bar ... * @param analysis: XPatternAnalysis, reference to holds Analysis result ... * @param config: XPatternAnalysisConfig, reference to Provides Detector Configs ... * * @return ( bool ) */ bool AnalyseBarPatterns( XOHCL &bar, XPatternAnalysis &analysis, XPatternAnalysisConfig &config // ) { // bool result = false; // // Prepare ... analysis.Clean(); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // analysis.bar = bar; analysis.time = TimeCurrent(); // XOHCL iSwing; XBoxZone iZone; ENUM_X_DIRECTION iDir; ENUM_X_BAR_PATTERN iPattern; // bool has; bool isBullish; bool isBearish; // bool canDetect; bool canDetectBullish; bool canDetectBearish; // // Bars Detectors ... // // XPV High Low Detection ... canDetect = config.CanDetect(X_BAR_PATTERN_HIGH) || config.CanDetect(X_BAR_PATTERN_LOW); if (canDetect) { // has = IsPV( bar, iDir, config.pvValidationLength, config.peakPriceType, config.valePriceType // ); // canDetectBullish = config.CanDetect(X_BAR_PATTERN_LOW); canDetectBearish = config.CanDetect(X_BAR_PATTERN_HIGH); // isBullish = has && IsXBullish(iDir) && canDetectBullish; // isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // iPattern = isBearish ? X_BAR_PATTERN_HIGH : X_BAR_PATTERN_LOW; // analysis.AddPattern( iPattern, iDir // ); } } // // Momentum ... iPattern = X_BAR_PATTERN_MOMENTUM; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsMomentumBar( bar, iDir, config.momentumBarValidationLength, config.momentumBarApprovedMultiplier // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Engulfed ... iPattern = X_BAR_PATTERN_ENGULFED; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsEngulfedBar( bar, iDir // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // TrueGap ... iPattern = X_BAR_PATTERN_TRUE_GAPED; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsTrueGapedBar( bar, iDir, config.trueGapApprovedStrength // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Pinned ... iPattern = X_BAR_PATTERN_PINNED; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsPinnedBar( bar, iDir, config.pinBarShadowApprovedMultiplier, config.pinBarRangeMultiplier, config.pinBarForceDirection // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Pattern Detectors ... // // Star ... iPattern = X_BAR_PATTERN_STAR; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsStarPattern( bar, iDir // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Piercing ... iPattern = X_BAR_PATTERN_PIERCING; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsPiercingPattern( bar, iDir // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Rising ... iPattern = X_BAR_PATTERN_RISING; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsRisingPattern( bar, iDir // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Flag ... iPattern = X_BAR_PATTERN_FLAG; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsFlagPattern( bar, iDir, iSwing, config.flagPatternPullbackLength // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); // analysis.flagSwing = iSwing; } } // // SignalKey ... iPattern = X_BAR_PATTERN_SIGNALKEY; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = IsSignalKeyBarPattern( bar, iDir, config.pinBarShadowApprovedMultiplier, config.pinBarRangeMultiplier, config.pinBarForceDirection // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && IsXBullish(iDir) && canDetectBullish; isBearish = has && IsXBearish(iDir) && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iDir // ); } } // // Zone Detectors ... // // OB ... iPattern = X_BAR_PATTERN_OB; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = barAnalyser.IsOB( bar, iZone, config.fvgForceType, config.obForceTwoBar // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && iZone.IsBullish() && canDetectBullish; isBearish = has && iZone.IsBearish() && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iZone.dir // ); // analysis.ob = iZone; } } // // FVG ... iPattern = X_BAR_PATTERN_FVG; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = barAnalyser.IsFVG( bar, iZone, config.fvgForceType // ); // canDetectBullish = config.CanDetect( iPattern, X_DIRECTION_BULLISH // ); canDetectBearish = config.CanDetect( iPattern, X_DIRECTION_BEARISH // ); // isBullish = has && iZone.IsBullish() && canDetectBullish; isBearish = has && iZone.IsBearish() && canDetectBearish; // canDetect = isBullish || isBearish; if (canDetect) { // analysis.AddPattern( iPattern, iZone.dir // ); // analysis.fvg = iZone; } } // // Support ... iPattern = X_BAR_PATTERN_SUPPORT; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = HasSupport( bar, iSwing, config.supportAndResistanceValidationLength, config.supportAndResistanceLoopbackLength // ); if (has) { // has = ToSupportBox( iSwing, iZone, bar.time, config.supportAndResistanceValidationLength // ); if (has) { // analysis.AddPattern( iPattern, iZone.dir // ); // analysis.support = iZone; } } } // // Resistance ... iPattern = X_BAR_PATTERN_RESISTANCE; canDetect = config.CanDetect(iPattern); if (canDetect) { // has = HasResistance( bar, iSwing, config.supportAndResistanceValidationLength, config.supportAndResistanceLoopbackLength // ); if (has) { // has = ToResistanceBox( iSwing, iZone, bar.time, config.supportAndResistanceValidationLength // ); if (has) { // analysis.AddPattern( iPattern, iZone.dir // ); // analysis.resistance = iZone; } } } // // Validate Analysis ... result = analysis.IsValid(); // // Cleanup Resources ... iZone.Clean(); iSwing.Clean(); CleanDirection(iDir); // return result; } /** * Collect Required Order Blocks ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dest: XBoxZone, collection reference to holds detected zones ... * @param zonesLoopback: int, zones detection loopback ... * @param maxRequiredZone: int, number of required zones ... * @param loopback: int, max allowed loopback lenght for zone Detection ... * * @return ( int ) */ int CollectOBs( XOHCL &bar, XBoxZone &dest[], int zonesLoopback = 5, int maxRequiredZone = 0, int loopback = 100 // ) { // int result = 0; // // Prepare ... XClean(dest); // // Normalize ... loopback = NormalizeInt(loopback, 10); zonesLoopback = NormalizeInt(zonesLoopback, 3); maxRequiredZone = NormalizeInt(maxRequiredZone, 0); // // Validate ... bool has = bar.IsValid(); if (!has) { return result; } // XOHCL iBar; XBoxZone iBox; ENUM_X_DIRECTION iDir; int start = bar.Index(); int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); iBox.Clean(); iDir = X_DIRECTION_NONE; // has = bar.BarAt(i, iBar); has = has && HasOB(iBar, iDir, iBox, zonesLoopback); if (has) { // AddIfNotExists( iBox, dest // ); } // has = maxRequiredZone <= 0 || (maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone); if (!has) { break; } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iBox.Clean(); iDir = X_DIRECTION_NONE; // return result; } /** * Collect Required Fair Value Gaps ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dest: XBoxZone, collection reference to holds detected zones ... * @param zonesLoopback: int, zones detection loopback ... * @param maxRequiredZone: int, number of required zones ... * @param loopback: int, max allowed loopback lenght for zone Detection ... * * @return ( int ) */ int CollectFVGs( XOHCL &bar, XBoxZone &dest[], int zonesLoopback = 5, int maxRequiredZone = 0, int loopback = 100 // ) { // int result = 0; // // Prepare ... XClean(dest); // // Normalize ... loopback = NormalizeInt(loopback, 10); zonesLoopback = NormalizeInt(zonesLoopback, 3); maxRequiredZone = NormalizeInt(maxRequiredZone, 0); // // Validate ... bool has = bar.IsValid(); if (!has) { return result; } // XOHCL iBar; XBoxZone iBox; ENUM_X_DIRECTION iDir; int start = bar.Index(); int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); iBox.Clean(); iDir = X_DIRECTION_NONE; // has = bar.BarAt(i, iBar); has = has && HasFVG(iBar, iDir, iBox, zonesLoopback); if (has) { // AddIfNotExists( iBox, dest // ); } // has = maxRequiredZone <= 0 || (maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone); if (!has) { break; } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iBox.Clean(); iDir = X_DIRECTION_NONE; // return result; } /** * Collect Required Support and Resistance Zones ... * * @param bar: XOHCL, reference to Specified Bar ... * @param dest: XBoxZone, collection reference to holds detected zones ... * @param zonesLoopback: int, zones detection loopback ... * @param zonesValidationLength: int, zones validation length ... * @param maxRequiredZone: int, number of required zones ... * @param loopback: int, max allowed loopback lenght for zone Detection ... * * @return ( int ) */ int CollectZones( XOHCL &bar, XBoxZone &dest[], int zonesLoopback = 5, int zonesValidationLength = 21, int maxRequiredZone = 0, int loopback = 100 // ) { // int result = 0; // // Prepare ... XClean(dest); // // Normalize ... loopback = NormalizeInt(loopback, 10); zonesLoopback = NormalizeInt(zonesLoopback, 3); maxRequiredZone = NormalizeInt(maxRequiredZone, 0); zonesValidationLength = NormalizeInt(zonesValidationLength, 3); // // Validate ... bool has = bar.IsValid(); if (!has) { return result; } // XOHCL iBar; XBoxZone iBox; XOHCL iZoneBar; int start = bar.Index(); int end = start + loopback; for (int i = start; i < end; i++) { // iBar.Clean(); iBox.Clean(); iZoneBar.Clean(); // has = bar.BarAt(i, iBar); if (!has) { continue; } // // Support ... has = HasSupport(iBar, iZoneBar, zonesValidationLength, zonesLoopback); if (has) { // has = ToSupportBox(iZoneBar, iBox, bar.time, zonesValidationLength); if (has) { // AddIfNotExists( iBox, dest // ); } } // // Resistance ... has = HasResistance(iBar, iZoneBar, zonesValidationLength, zonesLoopback); if (has) { // has = ToResistanceBox(iZoneBar, iBox, bar.time, zonesValidationLength); if (has) { // AddIfNotExists( iBox, dest // ); } } // has = maxRequiredZone <= 0 || (maxRequiredZone > 0 && ArraySize(dest) < maxRequiredZone); if (!has) { break; } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iBox.Clean(); iZoneBar.Clean(); // return result; } /** * Detect and Collect Required Zones ... * * @param bar: XOHCL, reference to Specified Bar ... * @param zones: XBoxZone, collection reference to holds detected zones ... * @param validateZones: bool, Specified to Detect only Valid Zones ... * @param containsOBs: bool, Flag to use Order Block Zones ... * @param containsFVGs: bool, Flag to use Fair Value Gap Zones ... * @param containsSupports: bool, Flag to use Support Zones ... * @param containsResistancess: bool, Flag to use Resistance Zones ... * @param forDir: ENUM_X_DIRECTION, Specified Zones Direction for Detecting ... * @param sortby: ENUM_X_SORT_BY, Specified Zones Sorting Factor ... * @param sortDir: ENUM_X_DIRECTION, Specified Zones Sorting Direction ... * @param zonesRangeValidationFactor: double, Specified Zones Range Validation in Points ... * @param zonesLoopback: int, loop back for Zones Detection ... * @param zonesValidationLength: int, zones Validation Length ... * @param count: int, number of required Zones ... * @param loopback: int, max allowed looping back lenght for detection ... * * @return ( int ) */ int DetectZones( XOHCL &bar, XBoxZone &zones[], bool validateZones = true, bool containsOBs = true, bool containsFVGs = true, bool containsSupports = true, bool containsResistancess = true, int loopback = 500, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, double zonesRangeValidationFactor = 10, int zonesLoopback = 5, int zonesValidationLength = 5, int count = 0 // ) { // int result = 0; // // Prepare ... XClean(zones); // // Normalize ... count = NormalizeInt(count, 0); loopback = NormalizeInt(loopback, 50); zonesLoopback = NormalizeInt(zonesLoopback, 2); zonesValidationLength = NormalizeInt(zonesValidationLength, 3); // // Validate ... bool has = bar.IsValid() && IsXValid(sortDir) && IsXValid(sortBy) && (containsOBs || containsFVGs || containsSupports || containsResistancess); if (!has) { return result; } // XOHCL iBar; XOHCL tmpBar; XPivot tmpPivot; XBoxZone tmpZone; ENUM_X_DIRECTION tmpDir; int idx = bar.Index(); while (idx < bar.Index() + loopback) { // idx++; // iBar.Clean(); tmpBar.Clean(); tmpZone.Clean(); tmpPivot.Clean(); // has = bar.BarAt(idx, iBar); if (!has) { continue; } // // Collecting Zones ... // // Support ... if (containsSupports) { // if (!HasDirection(forDir) || IsXBullish(forDir)) { // has = HasSupport(iBar, tmpBar, zonesValidationLength, zonesLoopback); if (has) { // has = ToBox(tmpBar, tmpZone, X_DIRECTION_BULLISH, X_BAR_PATTERN_SUPPORT); if (has) { AddIfNotExists(tmpZone, zones); } } } } // // Resistance ... if (containsResistancess) { // if (!HasDirection(forDir) || IsXBearish(forDir)) { // has = HasResistance(iBar, tmpBar, zonesValidationLength, zonesLoopback); if (has) { // has = ToBox(tmpBar, tmpZone, X_DIRECTION_BEARISH, X_BAR_PATTERN_RESISTANCE); if (has) { AddIfNotExists(tmpZone, zones); } } } } // // Order Block ... if (containsOBs) { // has = HasOB(iBar, tmpDir, tmpZone, zonesLoopback); if (has && (!HasDirection(forDir) || tmpDir == forDir)) { AddIfNotExists(tmpZone, zones); } } // // Fair Value Gaps ... if (containsFVGs) { // has = HasFVG(iBar, tmpDir, tmpZone, zonesLoopback); if (has && (!HasDirection(forDir) || tmpDir == forDir)) { AddIfNotExists(tmpZone, zones); } } } // // Validate Zones Exists ... result = ArraySize(zones); has = IsValidSize(result); if (!has) { return result; } // // Update Zones Time ... UpdateToTime(zones, bar.time); // // Validate Zones ... if (validateZones) { // // Apply Zones Validation Here ... RemoveBreakedZones(zones, true); } // // Validate Zones Range ... if (zonesRangeValidationFactor > 0) { // double points = GetPoints(bar.symbol); double minAllowedRange = points * zonesRangeValidationFactor; ValidateZonesRange(zones, minAllowedRange); } // // Apply Sorting ... Sort(zones, sortBy, sortDir); // // Validate Zones Count ... if (count > 0) { CleanupArray(zones, count); } // result = ArraySize(zones); // // Cleanup ... iBar.Clean(); tmpBar.Clean(); tmpZone.Clean(); tmpPivot.Clean(); // return result; } /** * Filter Zones ... * * @param bar: XOHCL, reference to Specified Filtering Bar ... * @param source: XBoxZone, reference collection to hold's filtered zones ... * @param filterDir: ENUM_X_DIRECTION, specified Filter Direction ... * @param priceType: ENUM_X_PRICE, Specified Bar's Price type to Use for Filtering Zones ... * @param forDir: ENUM_X_DIRECTION, Specified Zone's Direction to Handle Filtering ... * * @return ( int ) */ int FilterZones( XOHCL &bar, XBoxZone &source[], ENUM_X_DIRECTION filterDir, ENUM_X_PRICE priceType = X_PRICE_CLOSE, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XBoxZone tmp[]; Copy( source, tmp // ); XClean(source); // // Validate ... bool has = bar.IsValid() && HasChild(tmp) && IsXValid(priceType) && HasDirection(filterDir); if (!has) { // XClean(tmp); return result; } // XBoxZone iBox; double price = bar.GetPrice(priceType); bool isBullish = IsXBullish(filterDir); while (HasChild(tmp)) { // iBox = tmp[0]; ArrayRemove(tmp, 0, 1); // has = // // Direction Pass ... (!HasDirection(forDir) ? true : forDir == iBox.dir) // && // // Price Pass ... (isBullish ? price > iBox.lower : price < iBox.upper); if (has) { AddIfNotExists(iBox, source); } // iBox.Clean(); } // result = ArraySize(source); // // Cleanup ... XClean(tmp); iBox.Clean(); // return result; } // // Protected ... protected: // // // Tools / Actions ... /** * Check Zones and Manage them ... * * @param forBar: XOHCL, reference to Specified Bar ... * @param _zones: XBoxZone, reference to Specified Zone Collection ... * @param sortBy: X_SORT_BY_DATE, Sort Zones by ... * @param sortDir: ENUM_X_DIRECTION, Sort Zones in Direction ... * @param maxAllowed: int, Specified Max Allowed Zones ... */ void CheckZones( XOHCL &forBar, XBoxZone &_zones[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, int maxAllowed = 50 // ) { // // Normalize ... maxAllowed = NormalizeInt(maxAllowed, 0); // // Validate ... bool has = forBar.IsValid() && HasChild(_zones); if (!has) { return; } // // Looping Through Zones ... int count = ArraySize(_zones); for (int i = 0; i < count; i++) { // // Check Break ... has = IsXValid(_zones[i].breakAt); if (has) { continue; } // _zones[i].to = forBar.time; // // Check for Test ... has = IsTested( forBar, _zones[i] // ); if (has) { // Add( forBar.time, _zones[i].tests // ); } // // Check for Inside ... has = IsInside( forBar, _zones[i] // ); if (has) { // Add( forBar.time, _zones[i].insides // ); } // // Check for Break ... has = IsBreaked( forBar, _zones[i] // ); if (has) { // Add( forBar.time, _zones[i].breaks // ); } // // Check for Act ... has = IsActed( forBar, _zones[i] // ); if (has) { // Add( forBar.time, _zones[i].acteds // ); } // // Check for FakeBreakes ... has = IsFakeBreaked( forBar, _zones[i] // ); if (has) { // Add( forBar.time, _zones[i].fakeBreaks // ); } // // Check for Valid Breakes ... has = IsValidBreaked( forBar, _zones[i] // ); if (has) { _zones[i].breakAt = forBar.time; } } // // Apply Sort and Cleanup ... Sort( _zones, sortBy, sortDir, maxAllowed // ); } // // Private ... private: // // Props ... XCBarAnalyser *barAnalyser; // // Helpers ... /** * Clean Specified Referenced Direction ... * * @param dir: ENUM_X_DIRECTION */ void CleanDirection(ENUM_X_DIRECTION &dir) { dir = X_DIRECTION_NONE; } }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-md5.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCMD5 // Description: Provides MD5 Hashing Requirements ... // // // 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 // // START Definitions ... // // static uchar _md5_PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // #define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) #define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) #define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) // #define _md5_FF(a, b, c, d, x, s, ac) \ { \ (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ (a) = _md5_ROTATE_LEFT((a), (s)); \ (a) += (b); \ } // #define _md5_GG(a, b, c, d, x, s, ac) \ { \ (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ (a) = _md5_ROTATE_LEFT((a), (s)); \ (a) += (b); \ } // #define _md5_HH(a, b, c, d, x, s, ac) \ { \ (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ (a) = _md5_ROTATE_LEFT((a), (s)); \ (a) += (b); \ } // #define _md5_II(a, b, c, d, x, s, ac) \ { \ (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ (a) = _md5_ROTATE_LEFT((a), (s)); \ (a) += (b); \ } // #define _md5_INIT_STATE_0 0x67452301 #define _md5_INIT_STATE_1 0xefcdab89 #define _md5_INIT_STATE_2 0x98badcfe #define _md5_INIT_STATE_3 0x10325476 // #define _md5_S11 7 #define _md5_S12 12 #define _md5_S13 17 #define _md5_S14 22 // #define _md5_S21 5 #define _md5_S22 9 #define _md5_S23 14 #define _md5_S24 20 // #define _md5_S31 4 #define _md5_S32 11 #define _md5_S33 16 #define _md5_S34 23 // #define _md5_S41 6 #define _md5_S42 10 #define _md5_S43 15 #define _md5_S44 21 // // END Definitions ... // // // XCMD5 a library for Hashing ... class XCMD5 { // // Public Provides ... public: // // Protected Provides ... // // Constructor ... XCMD5(void) { } // // Deconstructor ... ~XCMD5(void) { } // // Hash Specified Char Array ... string Hash( uchar &mSource[], // Specify Char Array to Hash int mLength = 0 // Specify Length of Char Array which required to hash ) { // string result = ""; // int sourceCount = ArraySize(mSource); // // Validate Args ... if ( sourceCount <= 0 || (sourceCount > 0 && mLength > sourceCount)) { return result; } // // Normalize Args ... if (mLength == 0) { mLength = sourceCount; } // // Init MD5 ... MD5Init(); // // Update Buffer ... MD5Update(mSource, mLength); // // Calculate Result ... result = MD5Final(); // return result; } // // Hash Specified String ... string Hash( string mSource // Specified String ) { // string result = ""; // // Converts String to Char Array ... uchar bytes[]; StringToCharArray( mSource, bytes, 0, StringLen(mSource)); // result = Hash( bytes, ArraySize(bytes)); // return result; } protected: // // Private Provides ... private: // uint m_lMD5[4]; uint m_nCount[2]; uchar m_lpszBuffer[64]; // // Convert Byte to DWord ... void ByteToDWord(int &out[], uint &in[], uint len) { // uint i = 0; uint j = 0; // for (; j < len; i++, j += 4) { out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; } } // // Convert DWord to Byte ... void DWordToByte(uchar &out[], uint &in[], uint len) { // uint i = 0; uint j = 0; // for (; j < len; i++, j += 4) { // out[j] = (uchar)(in[i] & 0xff); out[j + 1] = (uchar)((in[i] >> 8) & 0xff); out[j + 2] = (uchar)((in[i] >> 16) & 0xff); out[j + 3] = (uchar)((in[i] >> 24) & 0xff); } } // // Init MD5 Array ... void MD5Init() { // ArrayInitialize(m_lpszBuffer, 64); // m_nCount[0] = m_nCount[1] = 0; m_lMD5[0] = _md5_INIT_STATE_0; m_lMD5[1] = _md5_INIT_STATE_1; m_lMD5[2] = _md5_INIT_STATE_2; m_lMD5[3] = _md5_INIT_STATE_3; } // // Update MD5 ... void MD5Update(uchar &inBuf[], uint inLen) { // int i, ii; int mdi; // uint in[16]; int i0 = 0; // mdi = (int)((m_nCount[0] >> 3) & 0x3F); // if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) { m_nCount[1]++; } // m_nCount[0] += ((uint)inLen << 3); m_nCount[1] += ((uint)inLen >> 29); // while ((inLen--) > 0) { // m_lpszBuffer[mdi++] = inBuf[i0++]; if (mdi == 0x40) { // for (i = 0, ii = 0; i < 16; i++, ii += 4) { in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); } // Transform(m_lMD5, in); // mdi = 0; } } } // // Finalize an MD5 Expression ... string MD5Final() { // uchar bits[8]; int nIndex; uint nPadLen; const int nMD5Size = 16; uchar lpszMD5[16]; string temp; string out = ""; int i; // DWordToByte(bits, m_nCount, 8); nIndex = (int)((m_nCount[0] >> 3) & 0x3f); nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); MD5Update(_md5_PADDING, nPadLen); MD5Update(bits, 8); DWordToByte(lpszMD5, m_lMD5, nMD5Size); // for (i = 0; i < nMD5Size; i++) { // if (lpszMD5[i] == 0) { temp = "00"; } else if (lpszMD5[i] <= 15) { temp = StringFormat("0%x", lpszMD5[i]); } else { temp = StringFormat("%x", lpszMD5[i]); } // out += temp; } // lpszMD5[0] = '\0'; // return (out); } // // Transform Buffers ... void Transform(uint &buf[], uint &in[]) { // uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; // _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); // _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); // _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); // _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); // buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-poi.drawer.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XPOIDrawer // Description: Provides Point of Interests // 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 "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... // // Implementations ... class XCPOIDrawer : public XCBase { // public: // // Props ... // XPOIStyle defaultBullishStyle; XPOIStyle defaultBearishStyle; // XPOIStyle boxBullishStyle; XPOIStyle boxBearishStyle; // CArrayObj drawnObjects; // // Constructor ... XCPOIDrawer() { // Default(); } // // Deconstructor ... ~XCPOIDrawer() { // boxBullishStyle.Clean(); boxBearishStyle.Clean(); defaultBullishStyle.Clean(); defaultBearishStyle.Clean(); } // // Setter Getter (s) ... /** * Get Prefix ... * * @return ( string ) */ string Prefix() { return mPrefix; } /** * Set Prifx ... * * @param value: String ... */ void Prefix(string value) { mPrefix = value; } /** * Get Chart ID ... * * @return ( long ) */ long ChartIdentification() { return mChartIdentification; } /** * Set Chart ID ... * * @param value: Long ... */ void ChartIdentification(long value) { // if (value < 0) { value = 0; } // mChartIdentification = value; } /** * Get SubWindow Id ... * * @return ( int ) */ int SubWindowIdentification() { return mSubWindowIdentification; } /** * Set SubWindow Id ... * * @param value: Integer ... */ void SubWindowIdentification(int value) { // if (value < 0) { value = 0; } // mSubWindowIdentification = value; } // // Virtuals ... /** * Apply Default Configurations ... */ virtual void Default() { // // Apply Default Props ... // Prefix(NULL); ChartIdentification(0); SubWindowIdentification(0); // defaultBullishStyle.width = 1; defaultBullishStyle.clr = clrLime; defaultBullishStyle.style = STYLE_SOLID; // defaultBearishStyle.width = 1; defaultBearishStyle.clr = clrRed; defaultBearishStyle.style = STYLE_SOLID; // boxBullishStyle = defaultBullishStyle; boxBearishStyle = defaultBearishStyle; } // // Drawers ... /** * Draw Specified Bar ... * * @param bar: XOHCL, refrence to Specified Bar ... * @param object: XCOHCLObject, pointer reference for Drawn Object ... * @param to: datetime, Specified To Time ... * * @return ( bool ) */ bool DrawBar( XOHCL &bar, XCOHCLObject *&object, datetime to = NULL // ) { // bool result = false; // // Prepare ... object = NULL; // // Validate ... result = bar.IsValid(); if (!result) { return result; } // string prefix = Prefix(); ulong chartId = ChartIdentification(); int window = SubWindowIdentification(); to = IsSpecifiedValid(to) ? to : ((datetime)((int)bar.time) + (PeriodSeconds(bar.period) - 1)); object = new XCOHCLObject(); result = object.Create( chartId, window, bar, to, prefix // ); if (result) { // ApplyBarStyle( object, bar // ); } // return result; } /** * Draw Bar Arrow Object ... * * @param bar: XOHCL instance Reference ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param priceType: ENUM_X_PRICE member ... * @param arrow: int, Arrow Code ... * @param clr: color, Arro Color ... * @param width: int, Arrow Width ... * @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ... * @param name: string, name of Arrow ... * * @return ( bool ) */ bool DrawBarArrow( XOHCL &bar, XCBarArrowObject *&object, ENUM_X_PRICE priceType, int arrow = 159, color clr = clrYellow, int width = 3, ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, string name = NULL, bool ignoreBarTag = true, int threshold = 5 // ) { // bool result = false; // object = NULL; // result = bar.IsValid(); if (!result) { return result; } // string barTag = bar.GetTag(name); // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // prefix = (IsValid(prefix) ? prefix + "_" : prefix) + (IsSpecifiedValid(name) ? name : "") + (ignoreBarTag ? "" : ToMD5(barTag)); // object = new XCBarArrowObject(); result = object .CreateByBar( chartID, prefix, window, arrow, bar, priceType, threshold // ); if (result) { // object.ArrowColor(clr); object.ArrowWidth(width); object.ArrowAnchor(anchor); } // return result; } /** * Dar Specified Pivot ... * * @param pivot: XPivot, Specified Pivot ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param threshold: int, distance between price and arrow in Point ... * * @return ( bool ) */ bool DrawPivot( XPivot &pivot, XCBarArrowObject *&object, int peakArrow = 159, int valeArrow = 159, int threshold = 5 // ) { // bool result = false; // // Prepare ... object = NULL; // // Normalize ... threshold = NormalizeInt(threshold, 5); peakArrow = NormalizeInt(peakArrow, 159); valeArrow = NormalizeInt(valeArrow, 159); // // Validate ... result = pivot.IsValid(); if (!result) { return result; } // // Get Pivot's Bar ... XOHCL bar; result = pivot.GetBar(bar); if (!result) { return result; } // int arrow = pivot.IsPeak() ? peakArrow : valeArrow; string name = pivot.GetObjectID(); ENUM_X_PRICE type = pivot.IsPeak() ? X_PRICE_HIGH : X_PRICE_LOW; XPOIStyle style = pivot.IsPeak() ? defaultBearishStyle : defaultBullishStyle; ENUM_ARROW_ANCHOR anchor = pivot.IsPeak() ? ANCHOR_BOTTOM : ANCHOR_TOP; object = new XCBarArrowObject(); result = object.CreateByBar( ChartIdentification(), name, SubWindowIdentification(), arrow, bar, type, threshold // ); if (result) { // // Apply Styles ... object.ArrowAnchor(anchor); ApplyBarArrowStyle( object, style // ); } // // Cleanup Resources ... bar.Clean(); // return result; } /** * Draw Specified Pivot Collection ... * * @param pivots: XPivot, reference Collection to Draw ... * @param draws: CArrayObj, pointer reference to Hold Drawn Objects ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param threshold: int, distance between price and arrow in Point ... * * @return ( int ) */ int DrawPivots( XPivot &pivots[], CArrayObj *&draws, int peakArrow = 159, int valeArrow = 159, int threshold = 5 // ) { // int result = 0; // // Prepare ... if (draws == NULL) { draws = new CArrayObj(); } draws.Clear(); // // Validate ... if (!HasChild(pivots)) { return result; } // bool has = false; XCBarArrowObject *iObj; int count = ArraySize(pivots); for (int i = 0; i < count; i++) { // // Draw Indexed Pivot ... has = DrawPivot( pivots[i], iObj, peakArrow, valeArrow, threshold // ); // if (has) { draws.Add(iObj); } // ZeroMemory(iObj); } // result = draws.Total(); // return result; } /** * Draw Specified Box ... * * @param object: XCBoxObject, pointer reference for Drawn Object ... * @param name: Box Name ... * @param upper: double, Box Upper ... * @param lower: double, Box Lower ... * @param from: datetime, From Time ... * @param to: datetime, To Time ... * @param at: datetime, Specified At Time ... * * @return ( bool ) */ bool DrawBox( XCBoxObject *&object, string name, double upper, double lower, datetime from, datetime to, datetime at // ) { // bool result = false; // // Prepare ... object = NULL; // // Normalize ... to = NormalizeTime(to); from = NormalizeTime(from); // // Validate ... result = upper > 0 && lower > 0 && to > from && IsSpecifiedValid(to) && IsSpecifiedValid(name) && IsSpecifiedValid(from) && upper > lower; if (!result) { return result; } // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // object = new XCBoxObject(); result = object.Create( chartID, window, name, upper, lower, from, to, at, prefix // ); // return result; } /** * Draw Specific Box ... * * @param box: XBoxZone, Specified Box ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param ignoreAt: bool, Ignore Box at or not ... * * @return ( bool ) */ bool DrawBox( XBoxZone &box, XCBoxObject *&object, bool ignoreAt = true, string name = NULL // ) { // bool result = false; // // Prepare ... object = NULL; // // Validate ... result = box.IsValid(); if (!result) { return result; } // datetime at = box.at; if (ignoreAt) { at = NULL; } // name = IsSpecifiedValid(name) ? name : box.GetTag(); result = DrawBox( object, name, box.upper, box.lower, box.from, box.to, at // ); if (result) { // // Apply Style ... XPOIStyle style; GetBoxStyle( style, box.dir // ); // ApplyBoxStyle( object, style // ); // style.Clean(); } // return result; } /** * Draw a Collection of Boxes ... * * @param boxes: reference collection to Provide Boxes ... * @param objects: reference pointer to holds drawn Objects ... * @param ignoreAt: bool, ignore Box At Drawn ... * * @return ( int ) */ int DrawBoxes( XBoxZone &boxes[], CArrayObj *&objects, bool useTypeName = true, bool ignoreAt = true // ) { // int result = 0; // // Prepare ... objects = new CArrayObj(); // // Validate ... if (!HasChild(boxes)) { return result; } // bool has = false; XCBoxObject *iObj; string name = NULL; int count = ArraySize(boxes); for (int i = 0; i < count; i++) { // if (useTypeName) { name = boxes[i].type; } // has = DrawBox( boxes[i], iObj, ignoreAt, name // ); if (has) { objects.Add(iObj); } // ZeroMemory(iObj); } // result = objects.Total(); // return result; } /** * Draw Specified Signal ... * * @param signal: XSignal, Specified Signal ... * @param object: XCSignalObject, pointer reference for Drawn Object ... * @param length: int, Signal Length ... */ bool DrawSignal( XSignal &signal, XCSignalObject *&object, int length = 3 // ) { // bool result = false; // object = NULL; length = NormalizeInt(length, 3); // result = signal.IsValid(); if (!result) { return result; } // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // object = new XCSignalObject(); result = object.Create( chartID, window, signal, length, prefix // ); if (!result) { return result; } // object.TPWidth(1); object.TPColor(clrGreen); object.TPWidth(STYLE_DOT); // object.SLWidth(1); object.SLColor(clrRed); object.SLWidth(STYLE_DOT); // object.TargetWidth(1); object.TargetColor(clrLightBlue); object.TargetWidth(STYLE_DOT); // object.EntryWidth(1); object.EntryColor(clrYellow); object.EntryWidth(STYLE_DOT); // return result; } /** * Draw Specified Trend Line ... * * @param fromPrice: double, from Price ... * @param fromTime: datetime, from Time ... * @param toPrice: double, to Price ... * @param toTime: datetime, to Time ... * @param object: CChartObjectTrend, pointer reference for Drawn Object ... * @param name: Object Name ... * @param rayRight: bool, ray to Right ... * @param rayLeft: boo, ray to Left ... * * @return ( bool ) */ bool DrawTrendLine( double fromPrice, datetime fromTime, double toPrice, datetime toTime, CChartObjectTrend *&object, string name, bool rayRight = false, bool rayLeft = false // ) { // bool result = false; // // Prepare ... object = new CChartObjectTrend(); // // Validate ... result = toPrice > 0 && fromPrice > 0 && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) && toTime > fromTime; if (!result) { return result; } // // Create Object ... result = object.Create( ChartIdentification(), name, SubWindowIdentification(), fromTime, fromPrice, toTime, toPrice // ); if (result) { // ENUM_X_DIRECTION dir = fromPrice < toPrice ? X_DIRECTION_BULLISH : fromPrice > toPrice ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; ApplyTrendLineStyle( object, dir // ); // object.RayLeft(rayLeft); object.RayRight(rayRight); } // return result; } /** * Draw Trend Line based on Swings Points ... * * @param swings: XOHCL, Specified Swings ... * @param dir: ENUM_X_DIRECTION, Specified Trend Direction ... * @param object: CChartObjectTrend, pointer reference for Drawn Object ... * @param rayRight: Ray to Right ... * @param rayLeft: Ray to Left ... * * @return ( bool ) */ bool DrawSwingTrend( XOHCL &swings[], ENUM_X_DIRECTION dir, CChartObjectTrend *&object, bool rayRight = false, bool rayLeft = false // ) { // bool result = false; // // Prepare ... object = NULL; // int count = ArraySize(swings); result = HasChild(swings) && count >= 2 && HasDirection(dir); if (!result) { return result; } // bool isBullish = IsSpecifiedBullish(dir); // XOHCL _swings[]; Copy( swings, _swings // ); SortBar( _swings, X_SORT_BY_DATE, X_DIRECTION_BULLISH // ); // double price1 = isBullish ? _swings[0].low : _swings[0].high; datetime time1 = _swings[0].time; // double price2 = isBullish ? _swings[count - 1].low : _swings[count - 1].high; datetime time2 = _swings[count - 1].time; // ulong chartId = ChartIdentification(); int subWindow = SubWindowIdentification(); string name = ToXString(dir) + "_Trend_" + ToXString(price1) + "_" + ToXString(price2); RemoveObjects("_Trend_", chartId, subWindow); // object = new CChartObjectTrend(); result = object.Create( chartId, name, subWindow, time1, price1, time2, price2 // ); if (result) { // ApplyTrendLineStyle( object, dir // ); // object.RayLeft(rayLeft); object.RayRight(rayRight); } // SpecifiedClean(_swings); // return result; } // // Stylers ... /** * Get Specified Style for Specified Direction ... * * @param style: XPOIStyle, reference to hold result ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void GetStyle( XPOIStyle &style, ENUM_X_DIRECTION forDir // ) { // // Prepare ... style.Clean(); // // Validate ... if (!HasDirection(forDir)) { return; } // if (IsSpecifiedBullish(forDir)) { style = defaultBullishStyle; } else { style = defaultBearishStyle; } } /** * Get Specified Box Style for Specified Direction ... * * @param style: XPOIStyle, reference to hold result ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void GetBoxStyle( XPOIStyle &style, ENUM_X_DIRECTION forDir // ) { // // Prepare ... style.Clean(); // // Validate ... if (!HasDirection(forDir)) { return; } // if (IsSpecifiedBullish(forDir)) { style = boxBullishStyle; } else { style = boxBearishStyle; } } /** * Apply Specified Style to Specified Object ... * * @param object: XCBoxObject, pointer reference of Object ... * @param bar: XOHCL, Specified Bar ... * @param fill: boolean, Fill Bar's Body or not ... */ void ApplyBarStyle( XCOHCLObject *&object, XOHCL &bar, bool fill = false // ) { // // Validate ... bool has = bar.IsValid() && object != NULL; if (!has) { return; } // XPOIStyle style; GetStyle( style, bar.GetDirection() // ); // object.BarSpes( style.width, style.clr, style.style, fill // ); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: XCBoxObject, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBoxStyle( XCBoxObject *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.BoxFill(style.fill); object.BoxColor(style.clr); object.BoxWidth(style.width); object.BoxStyle(style.style); } /** * Apply Specified Style to a Collection on Drawn Boxes ... * * @param objects: pointer reference of Objects ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBoxesStyle( CArrayObj *&objects, XPOIStyle &style // ) { // // Validate ... if (objects == NULL || objects.Total() <= 0) { return; } // for (int i = 0; i < objects.Total(); i++) { // XCBoxObject *iObj = ((XCBoxObject *)objects.At(i)); ApplyBoxStyle( iObj, style // ); ZeroMemory(iObj); } } /** * Apply Specified Style to Specified Object ... * * @param object: XCBarArrowObject, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBarArrowStyle( XCBarArrowObject *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.ArrowColor(style.clr); object.ArrowWidth(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectVLine, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyLineStyle( CChartObjectVLine *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.Color(style.clr); object.Style(style.style); object.Width(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectVLine, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyLineStyle( CChartObjectVLine *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // has = HasDirection(forDir); if (!has) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectHLine, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyLineStyle( CChartObjectHLine *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.Color(style.clr); object.Style(style.style); object.Width(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectHLine, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyLineStyle( CChartObjectHLine *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // has = HasDirection(forDir); if (!has) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectTrend, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyTrendLineStyle( CChartObjectTrend *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // if (!HasDirection(forDir)) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } // // SPecial Draws Functions ... /** * Draw Specified Pattern Pivot ... * * @param _pivot: XPivot, reference to Specified Pivot ... * @param config: XPOIDrawConfig, Darwing Configuration ... * @param thresholdMultiplier: int, pivot point threshold ... */ void DrawPivot( XPivot &_pivot, XPOIDrawConfig &config, int thresholdMultiplier = 0 // ) { // // Normalize ... thresholdMultiplier = NormalizeInt(thresholdMultiplier, 1); // int arrowThreshold = config.arrowsThreshold * thresholdMultiplier; arrowThreshold = NormalizeInt(arrowThreshold, 1); // // Validate ... bool has = _pivot.IsValid(); if (!has) { return; } // XOHCL _bar; has = _pivot.GetBar(_bar); if (!has) { // _bar.Clean(); return; } // XCBarArrowObject *iObj; has = DrawBarArrow( _bar, iObj, _pivot.IsPeak() ? config.arrowsPeakPriceType : config.arrowsValePriceType, _pivot.IsBullish() ? config.bullishArrow : config.bearishArrow, _pivot.IsBullish() ? config.bullishColor : config.bearishColor, config.arrowsWidth, _pivot.IsBullish() ? ANCHOR_TOP : ANCHOR_BOTTOM, _pivot.prefix + "_Pivot_" + ToXString(TimeToSeconds(_pivot.time)), true, // Ignore Bar Tag ... arrowThreshold // Threshold ... ); if (has) { drawnObjects.Add(iObj); } // ZeroMemory(iObj); } /** * Draw Specified Pattern Zone ... * * @param _zone: XBozxZone, reference to Specified Zone ... * @param config: XPOIDrawConfig, Darwing Configuration ... */ void DrawZone( XBoxZone &_zone, XPOIDrawConfig &config // ) { // // Validate ... bool has = _zone.IsValid(); if (!has) { return; } // XCBoxObject *iObj; has = DrawBox( _zone, iObj, config.ignoreZonesAt, _zone.type + "_Zone_" + ToXString(TimeToSeconds(_zone.from)) // ); if (has) { // XPOIStyle iStyle; GetBoxStyle( iStyle, _zone.dir // ); // iStyle.clr = _zone.IsBullish() ? config.bullishColor : config.bearishColor; iStyle.width = config.zonesWidth; iStyle.style = config.zonesStyle; // ApplyBoxStyle( iObj, iStyle // ); // drawnObjects.Add(iObj); // iStyle.Clean(); } // ZeroMemory(iObj); } /** * Draw Specified Zones ... * * @param _zone: XBozxZone, reference to Collection Specified Zone ... * @param config: XPOIDrawConfig, Darwing Configuration ... */ void DrawZones( XBoxZone &_zones[], XPOIDrawConfig &config // ) { // // Validate ... bool has = HasChild(_zones); if (!has) { return; } // for (int i = 0; i < ArraySize(_zones); i++) { // DrawZone( _zones[i], config // ); } } /** * Draw Pivots ... * * @param pivots: XPivot, collection reference to Draw ... * @param config: XPOIDrawConfig, reference to Specified Draw Style ... */ void DrawPivots( XPivot &pivots[], XPOIDrawConfig &config // ) { // // Validate ... bool has = HasChild(pivots); if (!has) { return; } // XPivot tmps[]; int count = ArraySize(pivots); for (int i = 0; i < count; i++) { // XClean(tmps); int sameCounts = ExtractSameTimePivots(pivots[i], tmps, pivots); has = IsValidSize(sameCounts); if (has) { // for (int j = 0; j < sameCounts; j++) { DrawPivot(tmps[j], config, j + 1); } } } // // Cleanup ... XClean(tmps); } void DrawTrendLine( string name, double fromPrice, datetime fromTime, double toPrice, datetime toTime, XPOIDrawConfig &config, color clr = CLR_NONE // ) { // // Validate ... bool has = IsXValid(name) && IsXValid(toTime) && IsXValid(fromTime) && NotEmptyZero(toPrice) && NotEmptyZero(fromPrice) && fromTime < toTime; if (!has) { return; } // ENUM_X_DIRECTION trendDir = fromPrice > toPrice ? X_DIRECTION_BEARISH : fromPrice < toPrice ? X_DIRECTION_BULLISH : X_DIRECTION_NONE; color clrTrend = (clr != CLR_NONE) ? clr : IsXBullish(trendDir) ? config.bullishColor : config.bearishColor; // CChartObjectTrend *object; has = DrawTrendLine( fromPrice, fromTime, toPrice, toTime, object, name, config.trendRayRight, config.trendRayLeft // ); if (has) { // // Apply Style ... object.Color(clrTrend); object.Width(config.trendWidth); object.Style(config.trendStyle); // // Save Object ... drawnObjects.Add(object); } // ZeroMemory(object); } void DrawTrendLine( XTrend &trend, XPOIDrawConfig &config, color clr = CLR_NONE // ) { // // Validate ... bool has = trend.IsValid(); if (!has) { return; } // color trendColor = (clr != CLR_NONE) ? clr : trend.IsBullish() ? config.bullishColor : trend.IsBearish() ? config.bearishColor : config.neuturalColor; string name = trend.GetObjectID(); // CChartObjectTrend *object; has = DrawTrendLine( trend.fromValue, trend.fromTime, trend.toValue, trend.toTime, object, name, config.trendRayRight, config.trendRayLeft // ); if (has) { // // Apply Style ... object.Color(trendColor); object.Width(config.trendWidth); object.Style(config.trendStyle); // // Save Object ... drawnObjects.Add(object); } // ZeroMemory(object); } /** * Draw Specified Pattern info ... * * @param _bar: XOHCL, reference to Pattern's Bar ... * @param _pivot: XPivot, reference to Pattern's Pivot ... * @param _zone: XBoxZone, reference to Pattern's Zone ... * @param _pattern: ENUM_X_BAR_PATTERN, Specified Bar Pattern ... * @param _patternDir: ENUM_X_DIRECTION, Specified Bar Pattern's Direction ... * @param thresholdMultiplier: int, pivot point threshold ... * @param config: XPOIDrawConfig, Darwing Configuration ... */ void DrawPattern( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_BAR_PATTERN _pattern, ENUM_X_DIRECTION _patternDir, XPOIDrawConfig &config, int thresholdMultiplier = 0 // ) { // // Validate ... bool has = _bar.IsValid() && IsXValid(_pattern) && HasDirection(_patternDir); if (!has) { return; } // datetime cTime = TimeCurrent(); // // Handle Draws ... // // Draw OHCL Bar ... // // Draw Pivot ... DrawPivot(_pivot, config, thresholdMultiplier); // // Draw Zone ... _zone.to = cTime; DrawZone(_zone, config); } /** * Draw Specified Bar Pattern Analysis ... * * @param analysis: XPatternAnalysis, reference to Specified Bar Pattern Analysis ... * @param config: XPatternAnalysisDrawConfig, reference to Provide Drawing Configuration ... */ void DrawPatternAnalysis( XPatternAnalysis &analysis, XPatternAnalysisDrawConfig &config // ) { // bool has = analysis.IsValid(); if (!has) { return; } // bool canDraw; bool isBullish; bool isBearish; XOHCL patternBar; bool canDrawZone; bool canDrawPivot; XPivot patternPivot; XBoxZone patternBox; ENUM_X_BAR_PATTERN pattern; ENUM_X_DIRECTION patternDir; // datetime cTime = TimeCurrent(); int patternsPivotThresholdMultiplier = 0; // // Support and Resistance ... // // Support ... isBearish = false; isBullish = analysis.IsSupport(); has = isBullish; if (has) { // pattern = X_BAR_PATTERN_SUPPORT; patternDir = X_DIRECTION_BULLISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Resistance ... isBullish = false; isBearish = analysis.IsResistance(); has = isBearish; if (has) { // pattern = X_BAR_PATTERN_RESISTANCE; patternDir = X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // PV: High and Low ... // // Low ... isBearish = false; isBullish = analysis.IsLow(); has = isBullish; if (has) { // pattern = X_BAR_PATTERN_LOW; patternDir = X_DIRECTION_BULLISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // High ... isBullish = false; isBearish = analysis.IsHigh(); has = isBearish; if (has) { // pattern = X_BAR_PATTERN_HIGH; patternDir = X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // OB ... isBullish = analysis.IsOB(X_DIRECTION_BULLISH); isBearish = analysis.IsOB(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_OB; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // FVG ... isBullish = analysis.IsFVG(X_DIRECTION_BULLISH); isBearish = analysis.IsFVG(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_FVG; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Momentum ... isBullish = analysis.IsMomentum(X_DIRECTION_BULLISH); isBearish = analysis.IsMomentum(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_MOMENTUM; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Engulfed ... isBullish = analysis.IsEngulfed(X_DIRECTION_BULLISH); isBearish = analysis.IsEngulfed(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_ENGULFED; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Pinned ... isBullish = analysis.IsPinned(X_DIRECTION_BULLISH); isBearish = analysis.IsPinned(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_PINNED; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // TrueGaped ... isBullish = analysis.IsTrueGaped(X_DIRECTION_BULLISH); isBearish = analysis.IsTrueGaped(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_TRUE_GAPED; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Star ... isBullish = analysis.IsStar(X_DIRECTION_BULLISH); isBearish = analysis.IsStar(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_STAR; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Piercing ... isBullish = analysis.IsPiercing(X_DIRECTION_BULLISH); isBearish = analysis.IsPiercing(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_PIERCING; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Rising ... isBullish = analysis.IsRising(X_DIRECTION_BULLISH); isBearish = analysis.IsRising(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_RISING; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Flag ... isBullish = analysis.IsFlag(X_DIRECTION_BULLISH); isBearish = analysis.IsFlag(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_FLAG; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // SignalKey ... isBullish = analysis.IsSignalKey(X_DIRECTION_BULLISH); isBearish = analysis.IsSignalKey(X_DIRECTION_BEARISH); has = isBullish || isBearish; if (has) { // pattern = X_BAR_PATTERN_SIGNALKEY; patternDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; canDraw = config.CanDraw(pattern); if (canDraw) { // has = analysis.GetPattern( patternBar, patternPivot, patternBox, pattern, patternDir // ); if (has) { // canDrawZone = config.CanDrawZone(pattern); if (!canDrawZone) { patternBox.Clean(); } // canDrawPivot = config.CanDrawPivot(pattern); if (!canDrawPivot) { patternPivot.Clean(); } else { patternsPivotThresholdMultiplier++; } // DrawPattern( patternBar, patternPivot, patternBox, pattern, patternDir, config.drawConfig, patternsPivotThresholdMultiplier // ); } } } // // Cleanup Resources ... patternBar.Clean(); patternBox.Clean(); patternPivot.Clean(); } /** * Draw a Collection of Pattern Analysis ... * * @param analysises: XPatternAnalysis, collection reference to Data Source ... * @param config: XPatternAnalysisDrawConfig, reference to Specified Drawing Config ... */ void DrawPatternAnalysises( XPatternAnalysis &analysises[], XPatternAnalysisDrawConfig &config // ) { // bool has = HasChild(analysises); if (!has) { return; } // int count = ArraySize(analysises); for (int i = 0; i < count; i++) { DrawPatternAnalysis(analysises[i], config); } } /** * Draw Specified Pivots Analysis ... * * @param analysis: XPivotAnalysis, reference to Specified Pivot Analysis ... * @param config: XPivotAnalysisDrawConfig, reference to Provide Drawing Configuration ... */ void DrawPivotAnalysis( XPivotAnalysis &analysis, XPivotAnalysisDrawConfig &config // ) { // bool has = analysis.IsValid(); if (!has) { return; } // int count = 0; XBoxZone tmpBox; datetime cTime = TimeCurrent(); // // Pivots ... if (config.drawPivots) { // has = analysis.HasPivots(); if (has) { // count = ArraySize(analysis.pivots); for (int i = 0; i < count; i++) { // DrawPivot( analysis.pivots[i], config.drawConfig // ); } } } // // Support ... if (config.drawSupport) { // tmpBox.Clean(); has = analysis.HasSupportBox(tmpBox); if (has) { // tmpBox.to = cTime; DrawZone( tmpBox, config.drawConfig // ); } } // // Resistance ... if (config.drawResistance) { // tmpBox.Clean(); has = analysis.HasResistanceBox(tmpBox); if (has) { // tmpBox.to = cTime; DrawZone( tmpBox, config.drawConfig // ); } } // // Peak Trend ... if (config.drawPeakTrend) { // has = analysis.IsPeakAnalysed(); if (has) { // string iUpperName = analysis.GetUpperObjectID(); CChartObjectTrend *iObj = new CChartObjectTrend(); has = iObj.Create( ChartIdentification(), iUpperName, SubWindowIdentification(), analysis.fromTime, analysis.peakFrom, analysis.toTime, analysis.peakTo // ); if (has) { // // Styling ... iObj.RayLeft(config.rayLeftTrends); iObj.RayRight(config.rayRightTrends); iObj.Width(config.drawConfig.zonesWidth); iObj.Style(config.drawConfig.zonesStyle); iObj.Color(IsXBullish(analysis.peakDir) ? config.drawConfig.bullishColor : config.drawConfig.bearishColor); // // Storing ... drawnObjects.Add(iObj); } } } // // Vale Trend ... if (config.drawValeTrend) { // has = analysis.IsValeAnalysed(); if (has) { // string iLowerName = analysis.GetLowerObjectID(); CChartObjectTrend *iObj = new CChartObjectTrend(); has = iObj.Create( ChartIdentification(), iLowerName, SubWindowIdentification(), analysis.fromTime, analysis.valeFrom, analysis.toTime, analysis.valeTo // ); if (has) { // // Styling ... iObj.RayLeft(config.rayLeftTrends); iObj.RayRight(config.rayRightTrends); iObj.Width(config.drawConfig.zonesWidth); iObj.Style(config.drawConfig.zonesStyle); iObj.Color(IsXBullish(analysis.valeDir) ? config.drawConfig.bullishColor : config.drawConfig.bearishColor); // // Storing ... drawnObjects.Add(iObj); } } } // // Cleanup ... tmpBox.Clean(); // } protected: // // private: // // // Props ... // string mPrefix; // Prefix of Created Objects ... long mChartIdentification; // Chart Id ... int mSubWindowIdentification; // Sub Window ... // }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-position.drawer.class.mq5 /////////////////////////////////////////////////////// // // 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; // Window ID of Chart ... ulong chartID; // Chart ID ... XCTrade *trader; // XCTrade Instance ... XPOIStyle riskStyle; // Risk Box Style ... color inProfitColor; // In Profit Price Box Color ... color inDrawdownColor; // In Drawdown Price Box Color ... ENUM_LINE_STYLE priceStyle; // Price Box Style ... XPOIStyle rewardStyle; // Reward Box Style ... CArrayObj positionObjects; // Drawn Positions Object Instances Collection ... CArrayObj finalizedObjects; // Finalized Drawn Positions Object Instances Collection ... // // Constructor ... XCPositionDrawer( XCTrade *_trader, ulong _chartID = 0, int _window = 0 // ) : XCBase() { // Init( _trader, _chartID, _window // ); } // // Deconstructor ... ~XCPositionDrawer() { Destroy(); } // // Tools ... /** * Initialize Class Instance ... * * @param _trader: XCTrade, reference Pointer to Trader Instance Class ... * @param _chartID: ulong, Specified Chart ID ... * @param _window: int, Specified Chart Window ID ... */ 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; // // Prepare Default Styles ... // // Risk Style ... riskStyle.width = 1; riskStyle.fill = false; riskStyle.clr = clrRed; riskStyle.style = STYLE_DASH; // // Reward Style ... rewardStyle.width = 1; rewardStyle.fill = false; rewardStyle.clr = clrLime; rewardStyle.style = STYLE_DASH; // // Price Style ... priceStyle = STYLE_SOLID; inProfitColor = clrAqua; // ApplyAlpha(clrAqua, 100); inDrawdownColor = clrMagenta; // ApplyAlpha(clrMagenta, 100); } /** * Destroy Instance ... */ void Destroy() { // riskStyle.Clean(); rewardStyle.Clean(); // positionObjects // finalizedObjects } /** * Validate Instance ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = trader != NULL; // return result; } /** * Update Positions ... * * @param barIndex: int, Specified Bar Index ... */ 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) { // // Update Position Object ... 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 ... has = ((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 = new XCPositionObject(); has = iObj.Create( chartID, window, iPosition // ); if (has) { // // Set Stylers to Position ... iObj.riskStyle = riskStyle; iObj.priceStyle = priceStyle; iObj.rewardStyle = rewardStyle; iObj.inProfitColor = inProfitColor; iObj.inDrawdownColor = inDrawdownColor; // // Add to Collection ... positionObjects.Add(iObj); } } // // 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); } /** * 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 // ) { // // Detect Position Index ... int index = FindIndex(ticket); bool has = IsValidIndex(index); if (!has) { return; } // // Get Position of Objects ... XPosition _position; has = ((XCPositionObject *)positionObjects.At(index)).GetPosition(_position); if (has) { // // Get Position of Trader Instance ... has = trader.GetPosition( ticket, _position // ); if (has) { // // Update Position ... ((XCPositionObject *)positionObjects.At(index)).Update(_position); } } // // Cleanup Resources ... _position.Clean(); } // // Protected ... protected: // /** * Finalize Specified Position ... * Remove it From Position Objects and add it to Finalized Objects Cllection ... * * @param ticket: ulong, Specified Position Ticket ... */ 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); } /** * Find Specified Position Index ... * * @param ticket: ulong, Specified Position Ticket ... * * @return ( int ) */ 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: // // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-restrictions.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCRestrictions // Description: provides all Requirements for Apply Restrictions ... // // // 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 "../Libraries/x-saherelm.x-trade.lib.mq5" // #region Definitions ... // // Awailable Restrictions Period ... enum ENUM_X_TRADE_RESTRICTIONS_PERIOD { X_TRADE_RESTRICATION_NONE, // None X_TRADE_RESTRICATION_HOURLY, // Per Hour X_TRADE_RESTRICATION_DAILY, // Per Day X_TRADE_RESTRICATION_WEEKLY, // Per Week X_TRADE_RESTRICATION_MONTHLY, // Per Month }; // #region Extensions ... // // Converts to String ... string ToXString(ENUM_X_TRADE_RESTRICTIONS_PERIOD value) { // string result = NULL; // result = EnumToString(value); // return result; } // // Check Has Restrictions or not ... bool HasXRestrictions(ENUM_X_TRADE_RESTRICTIONS_PERIOD value) { // bool result = false; // result = value != X_TRADE_RESTRICATION_NONE; // return result; } /** * Get Restrictions Period Delay in Seconds ... * * @param value: ENUM_X_TRADE_RESTRICTIONS_PERIOD ... * * @return ( int ) */ int RestrictionsPeriodSeconds(ENUM_X_TRADE_RESTRICTIONS_PERIOD value) { // int result = 0; // // Check Restrictions is Valid or not ... if (!HasXRestrictions(value)) { return result; } // switch (value) { // default: case X_TRADE_RESTRICATION_NONE: result = 0; break; // case X_TRADE_RESTRICATION_HOURLY: result = PeriodSeconds(PERIOD_H1); break; // case X_TRADE_RESTRICATION_DAILY: result = PeriodSeconds(PERIOD_D1); break; // case X_TRADE_RESTRICATION_WEEKLY: result = PeriodSeconds(PERIOD_W1); break; // case X_TRADE_RESTRICATION_MONTHLY: result = PeriodSeconds(PERIOD_MN1); break; } // return result; } /** * Calculate Restrictions End Time ... * * @param value: ENUM_X_TRADE_RESTRICTIONS_PERIOD ... * @param multiplier: int, Restrictions Period Multiplier ... * @param fromTime: Restrictions Starts Time ... * * @return ( datetime ) */ datetime RestrictionsEndTime( ENUM_X_TRADE_RESTRICTIONS_PERIOD value, int multiplier = 1, datetime fromTime = NULL // ) { // datetime result = NULL; // // Normalize Multiplier ... if (multiplier < 1) { multiplier = 1; } if (!IsXValid(fromTime)) { fromTime = TimeCurrent(); } // // Calculate Requirements ... int periodSeconds = RestrictionsPeriodSeconds(value); int timeInSeconds = (int)fromTime + (periodSeconds * multiplier); MqlDateTime timeStruct; bool hasStruct = TimeToStruct( (datetime)timeInSeconds, timeStruct // ); if (hasStruct) { // timeStruct.min = 0; timeStruct.sec = 0; // result = StructToTime(timeStruct); } else { result = (datetime)timeInSeconds; } // ZeroMemory(timeStruct); // return result; } // #endregion // #region Event Handler Types ... typedef void (*TRestrictionEvent)(); // #endregion // #endregion // // Implementation ... class XCRestrictions : public XCBase { // // Public ... public: // // Props ... // // Constructor ... XCRestrictions() { // Clean(); Default(); } // // Deconstructor ... ~XCRestrictions() { // Clean(); } // #region Properties ... // #region RestrictionsPeriod ... /** * Get Restrictions Period ... * * @return ( ENUM_X_TRADE_RESTRICTIONS_PERIOD ) */ ENUM_X_TRADE_RESTRICTIONS_PERIOD GetRestrictionsPeriod() { return mRestrictionsPeriod; } /** * Get Restrictions Period ... * * @param value: ENUM_X_TRADE_RESTRICTIONS_PERIOD */ void SetRestrictionsPeriod(ENUM_X_TRADE_RESTRICTIONS_PERIOD value) { mRestrictionsPeriod = value; } // #endregion // #region Restrictions Period Multiplier ... /** * Get Restrictions Period Multiplier ... * * @return ( int ) */ int GetRestrictionsPeriodMultiplier() { return mRestrictionsPeriodMultiplier; } /** * Set Restrictions Period Multiplier ... * * @param value: int ... */ void SetRestrictionsPeriodMultiplier(int value) { // if (value < 1) { value = 1; } // mRestrictionsPeriodMultiplier = value; } // #endregion // #region Signals ... /** * Get Issued Signals ... * * @return ( int ) */ int GetSignals() { return mSignals; } /** * Get Issued Long Signals ... * * @return ( int ) */ int GetLongSignals() { return mLongSignals; } /** * Issued Short Signals ... * * @return ( int ) */ int GetShortSignals() { return mShortSignals; } /** * Get Issued Signals in Restrictions Period ... * * @return ( int ) */ int GetRestrictedSignals() { return mRestrictedSignals; } /** * Get Issued Long Signals in Restrictions Period ... * * @return ( int ) */ int GetRestrictedLongSignals() { return mRestrictedLongSignals; } /** * Get Issued Short Signals in Restrictions Period ... * * @return ( int ) */ int GetRestrictedShortSignals() { return mRestrictedShortSignals; } /** * Get Allowed Signals in Restrictions Period ... * * @return ( int ) */ int GetAllowedSignalsInRestrictions() { return mAllowedSignalsInRestrictions; } /** * Set Allowed Signals in Restrictions Period ... * * @param value: int ... */ void SetAllowedSignalsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedSignalsInRestrictions = value; } /** * Get Allowed Long Signals in Restrictions Period ... * * @return ( int ) */ int GetAllowedLongSignalsInRestrictions() { return mAllowedLongSignalsInRestrictions; } /** * Set Allowed Long Signals in Restrictions Period ... * * @param value: int ... */ void SetAllowedLongSignalsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedLongSignalsInRestrictions = value; } /** * Get Allowed Short Signals in Restrictions Period ... * * @return ( int ) */ int GetAllowedShortSignalsInRestrictions() { return mAllowedShortSignalsInRestrictions; } /** * Set Allowed Short Signals in Restrictions Period ... * * @param value: int ... */ void SetAllowedShortSignalsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedShortSignalsInRestrictions = value; } // #endregion // #region Trades ... /** * Executed Trades ... * * @return ( int ) */ int GetTrades() { return mTrades; } /** * Executed Long Trades ... * * @return ( int ) */ int GetLongTrades() { return mLongTrades; } /** * Executed Short Trades ... * * @return ( int ) */ int GetShortTrades() { return mShortTrades; } /** * Executed Trades in Restrictions Period ... * * @return ( int ) */ int GetRestrictedTrades() { return mRestrictedTrades; } /** * Executed Long Trades in Restrictions Period ... * * @return ( int ) */ int GetRestrictedLongTrades() { return mRestrictedLongTrades; } /** * Executed Short Trades in Restrictions Period ... * * @return ( int ) */ int GetRestrictedShortTrades() { return mRestrictedShortTrades; } /** * Get Allowed Trades in Restrictions Period ... * * @return ( int ) */ int GetAllowedTradesInRestrictions() { return mAllowedTradesInRestrictions; } /** * Set Allowed Trades in Restrictions Period ... * * @param value: int ... */ void SetAllowedTradesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedTradesInRestrictions = value; } /** * Get Allowed Long Trades in Restrictions Period ... * * @return ( int ) */ int GetAllowedLongTradesInRestrictions() { return mAllowedLongTradesInRestrictions; } /** * Set Allowed Long Trades in Restrictions Period ... * * @param value: int ... */ void SetAllowedLongTradesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedLongTradesInRestrictions = value; } /** * Get Allowed Short Trades in Restrictions Period ... * * @return ( int ) */ int GetAllowedShortTradesInRestrictions() { return mAllowedShortTradesInRestrictions; } /** * Set Allowed Short Trades in Restrictions Period ... * * @param value: int ... */ void SetAllowedShortTradesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedShortTradesInRestrictions = value; } // #endregion // #region Wins ... /** * Touched Wins ... * * @return ( int ) */ int GetWins() { return mWins; } /** * Touched Long Wins ... * * @return ( int ) */ int GetLongWins() { return mLongWins; } /** * Touched Short Wins ... * * @return ( int ) */ int GetShortWins() { return mShortWins; } /** * Touched Wins in Restrictions Period ... * * @return ( int ) */ int GetRestrictedWins() { return mRestrictedWins; } /** * Touched Long Wins in Restrictions Period ... * * @return ( int ) */ int GetRestrictedLongWins() { return mRestrictedLongWins; } /** * Touched Short Wins in Restrictions Period ... * * @return ( int ) */ int GetRestrictedShortWins() { return mRestrictedShortWins; } /** * Get Allowed Wins in Restrictions Period ... * * @return ( int ) */ int GetAllowedWinsInRestrictions() { return mAllowedWinsInRestrictions; } /** * Set Allowed Wins in Restrictions Period ... * * @param value: int ... */ void SetAllowedWinsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedWinsInRestrictions = value; } /** * Get Allowed Long Wins in Restrictions Period ... * * @return ( int ) */ int GetAllowedLongWinsInRestrictions() { return mAllowedLongWinsInRestrictions; } /** * Set Allowed Long Wins in Restrictions Period ... * * @param value: int ... */ void SetAllowedLongWinsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedLongWinsInRestrictions = value; } /** * Get Allowed Short Wins in Restrictions Period ... * * @return ( int ) */ int GetAllowedShortWinsInRestrictions() { return mAllowedShortWinsInRestrictions; } /** * Set Allowed Short Wins in Restrictions Period ... * * @param value: int ... */ void SetAllowedShortWinsInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedShortWinsInRestrictions = value; } // #endregion // #region Losess ... /** * Touched Loses ... * * @return ( int ) */ int GetLoses() { return mLoses; } /** * Touched Long Loses ... * * @return ( int ) */ int GetLongLoses() { return mLongLoses; } /** * Touched Short Loses ... * * @return ( int ) */ int GetShortLoses() { return mShortLoses; } /** * Touched Loses in Restrictions Period ... * * @return ( int ) */ int GetRestrictedLoses() { return mRestrictedLoses; } /** * Touched Long Loses in Restrictions Period ... * * @return ( int ) */ int GetRestrictedLongLoses() { return mRestrictedLongLoses; } /** * Touched Short Loses in Restrictions Period ... * * @return ( int ) */ int GetRestrictedShortLoses() { return mRestrictedShortLoses; } /** * Get Allowed Loses in Restrictions Period ... * * @return ( int ) */ int GetAllowedLosesInRestrictions() { return mAllowedLosesInRestrictions; } /** * Set Allowed Loses in Restrictions Period ... * * @param value: int ... */ void SetAllowedLosesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedLosesInRestrictions = value; } /** * Get Allowed Long Loses in Restrictions Period ... * * @return ( int ) */ int GetAllowedLongLosesInRestrictions() { return mAllowedLongLosesInRestrictions; } /** * Set Allowed Long Loses in Restrictions Period ... * * @param value: int ... */ void SetAllowedLongLosesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedLongLosesInRestrictions = value; } /** * Get Allowed Short Loses in Restrictions Period ... * * @return ( int ) */ int GetAllowedShortLosesInRestrictions() { return mAllowedShortLosesInRestrictions; } /** * Set Allowed Short Loses in Restrictions Period ... * * @param value: int ... */ void SetAllowedShortLosesInRestrictions(int value) { // if (value < 0) { value = 0; } // mAllowedShortLosesInRestrictions = value; } // #endregion // #region Current Restrictions ... /** * Get Current Restrictions End Time ... * * @return ( datetime ) */ datetime GetCurrentRestrictionsEnd() { return mRestrictionsEnd; } /** * Get Current Restrictions Start Time ... * * @return ( datetime ) */ datetime GetCurrentRestrictionsStart() { return mRestrictionsStart; } // #endregion // #endregion // #region Tools ... /** * Check Restrictions Exists or not ... * * @return ( bool ) */ bool HasRestrictions() { // bool result = false; // result = HasXRestrictions(mRestrictionsPeriod); // return result; } /** * Handle Signal Issued ... * * @param signal: XSignal ... */ void HandleSignal(XSignal &signal) { // if (!signal.IsValid()) { return; } // bool isLong = IsLong(signal.type); // mSignals++; // if (isLong) { mLongSignals++; } else { mShortSignals++; } // if (HasRestrictions()) { // mRestrictedSignals++; // if (isLong) { mRestrictedLongSignals++; } else { mRestrictedShortSignals++; } } } /** * Handle Signal Execution ... * * @param signal: XSignal ... */ void HandleTrade(XSignal &signal) { // if (!signal.IsValid()) { return; } bool isLong = IsLong(signal.type); // mTrades++; // if (isLong) { mLongTrades++; } else { mShortTrades++; } // if (HasRestrictions()) { // mRestrictedTrades++; // if (isLong) { mRestrictedLongTrades++; } else { mRestrictedShortTrades++; } } } /** * Handle Trade Win ... * * @param type: ENUM_X_POSITION_TYPES ... */ void HandleTradeWin(ENUM_X_POSITION_TYPES type) { // if (!IsXValid(type)) { return; } bool isLong = IsLong(type); // mWins++; // if (isLong) { mLongWins++; } else { mShortWins++; } // if (HasRestrictions()) { // mRestrictedWins++; // if (isLong) { mRestrictedLongWins++; } else { mRestrictedShortWins++; } } } /** * Handle Trade Lose ... * * @param type: ENUM_X_POSITION_TYPES ... */ void HandleTradeLose(ENUM_X_POSITION_TYPES type) { // if (!IsXValid(type)) { return; } bool isLong = IsLong(type); // mLoses++; // if (isLong) { mLongLoses++; } else { mShortLoses++; } // if (HasRestrictions()) { // mRestrictedLoses++; // if (isLong) { mRestrictedLongLoses++; } else { mRestrictedShortLoses++; } } } /** * Check Allow Issue Signal or not ... * * @param signal: XSignal ... * * @return ( bool ) */ bool CheckAllowIssueSignal(XSignal &signal) { // bool result = false; // // Validate Signal ... result = signal.IsValid(); if (!result) { return result; } bool isLong = IsLong(signal.type); // // Check if Restrictions Exists ... if (!HasRestrictions()) { return result; } // // Check Signal Restrictions ... if (result) { // if (IsValidSize(mAllowedSignalsInRestrictions)) { // result = result && mRestrictedLongSignals < mAllowedSignalsInRestrictions; } } // // Check Long Signal Restrictions ... if (result) { // if (isLong && IsValidSize(mAllowedLongSignalsInRestrictions)) { // result = result && mRestrictedLongSignals < mAllowedLongSignalsInRestrictions; } } // // Check Short Signal Restrictions ... if (result) { // if (!isLong && IsValidSize(mAllowedShortSignalsInRestrictions)) { // result = result && mRestrictedShortSignals < mAllowedShortSignalsInRestrictions; } } // return result; } /** * Check Allow Issue Signal or not ... * * @param signal: XSignal ... * * @return ( bool ) */ int CheckAllowExecuteSignal(XSignal &signal) { // bool result = false; // // Validate Signal ... result = signal.IsValid(); if (!result) { return result; } bool isLong = IsLong(signal.type); // // Check if Restrictions Exists ... if (!HasRestrictions()) { return result; } // // Check Trade Restrictions ... if (result) { // if (IsValidSize(mAllowedTradesInRestrictions)) { // result = result && mRestrictedTrades < mAllowedTradesInRestrictions; } } // // Check Long Trade Restrictions ... if (result) { // if (IsValidSize(mAllowedLongTradesInRestrictions)) { // result = result && mRestrictedLongTrades < mAllowedLongTradesInRestrictions; } } // // Check Short Trade Restrictions ... if (result) { // if (IsValidSize(mAllowedShortTradesInRestrictions)) { // result = result && mRestrictedShortTrades < mAllowedShortTradesInRestrictions; } } // // Check Wins Restrictions ... if (result) { // if (IsValidSize(mAllowedWinsInRestrictions)) { // result = result && mRestrictedWins < mAllowedWinsInRestrictions; } } // // Check Long Wins Restriction ... if (result) { // if (IsValidSize(mAllowedLongWinsInRestrictions)) { // result = result && mRestrictedLongWins < mAllowedLongWinsInRestrictions; } } // // Check Short Wins Restriction ... if (result) { // if (IsValidSize(mAllowedShortWinsInRestrictions)) { // result = result && mRestrictedShortWins < mAllowedShortWinsInRestrictions; } } // // Check Lose Restrictions ... if (result) { // if (IsValidSize(mAllowedLosesInRestrictions)) { // result = result && mRestrictedLoses < mAllowedLosesInRestrictions; } } // // Check Long Lose Restrictions ... if (result) { // if (IsValidSize(mAllowedLongLosesInRestrictions)) { // result = result && mRestrictedLongLoses < mAllowedLongLosesInRestrictions; } } // // Check Short Lose Restrictions ... if (result) { // if (IsValidSize(mAllowedShortLosesInRestrictions)) { // result = result && mRestrictedShortLoses < mAllowedShortLosesInRestrictions; } } // return result; } // #endregion // #region Event Handlers Registrations ... /** * Register Restrictions Start Event Handler ... * * @param handler: TRestrictionEvent ... */ void AddRestrictionsStartEventHandler(TRestrictionEvent handler) { // if (handler == NULL) { return; } // Add(handler, mOnRestrictionsStartEventHandlers); } /** * Register Restrictions End Event Handler ... * * @param handler: TRestrictionEvent ... */ void AddRestrictionsEndEventHandler(TRestrictionEvent handler) { // if (handler == NULL) { return; } // Add(handler, mOnRestrictionsEndEventHandlers); } // #endregion /** * Process Ticks for Restrictions ... * Applied Eac Secconds ... */ void Process() { // // Check Restrictions Exists or not ... if (!HasRestrictions()) { return; } // // Calculate Requirements ... datetime currentTime = TimeCurrent(); // // Check Current Restrictions Exists or not ... // Initial Restrictions Period if not Exists ... if (!IsXValid(mRestrictionsStart)) { // // Initial Restrictions ... mRestrictionsStart = currentTime; mRestrictionsEnd = RestrictionsEndTime( mRestrictionsPeriod, mRestrictionsPeriodMultiplier, mRestrictionsStart // ); // // Loging Restrictions Start ... LogRestrictionsStart(); // // Notfy Restrictions Start Event Handlers ... NotifyRestrictionsStartEventHandlers(); // return; } // // Validate Current Restrictions ... // // Check Process Exists or not ... if (IsXValid(mLastCheck)) { // // Validate New Check Must Happens after 1 Minute ... bool canCheck = currentTime >= mLastCheck + 60; if (!canCheck) { return; } } // // Update Last Check ... mLastCheck = currentTime; // // Check Restrictions End ... bool isEnded = currentTime >= mRestrictionsEnd; if (isEnded) { // // Fire Restrictions End Event Handlers ... NotifyRestrictionsEndEventHandlers(); // // Logging Resrtrictions Summary if Required ... LogRestrictionsEnd(); // // Reset Restrictions ... ResetRestrictions(); // return; } // // TODO: Implement What we want if necessary ... } // // Protected ... protected: // // Props ... /** * Cleanup ... */ void Clean() { // mAllowedWinsInRestrictions = 0; mAllowedLongWinsInRestrictions = 0; mAllowedShortWinsInRestrictions = 0; // mAllowedLosesInRestrictions = 0; mAllowedLongLosesInRestrictions = 0; mAllowedShortLosesInRestrictions = 0; // mAllowedSignalsInRestrictions = 0; mAllowedLongSignalsInRestrictions = 0; mAllowedShortSignalsInRestrictions = 0; // mAllowedTradesInRestrictions = 0; mAllowedLongTradesInRestrictions = 0; mAllowedShortTradesInRestrictions = 0; // ResetRestrictions(); XClean(mOnRestrictionsEndEventHandlers); XClean(mOnRestrictionsStartEventHandlers); } /** * Set Default Values ... */ void Default() { // mRestrictionsPeriodMultiplier = 1; mRestrictionsPeriod = X_TRADE_RESTRICATION_NONE; } /** * Logging Restrictions Start Summary ... */ void LogRestrictionsStart() { } /** * Logging Restrictions End Summary ... */ void LogRestrictionsEnd() { } // #region Event Handlers Notifier ... /** * Notify Registered Restrictions Start Event Handlers ... */ void NotifyRestrictionsStartEventHandlers() { // int count = ArraySize(mOnRestrictionsStartEventHandlers); if (!IsValidSize(count)) { return; } // for (int i = 0; i < count; i++) { mOnRestrictionsStartEventHandlers[i](); } } /** * Notify Registered Restrictions End Event Handlers ... */ void NotifyRestrictionsEndEventHandlers() { // int count = ArraySize(mOnRestrictionsEndEventHandlers); if (!IsValidSize(count)) { return; } // for (int i = 0; i < count; i++) { mOnRestrictionsEndEventHandlers[i](); } } // #endregion // #region Restrictions Summary Cleaners ... /** * Reset all Restricted Counters ... */ void ResetRestrictions() { // mRestrictionsEnd = NULL; mRestrictionsStart = NULL; // ResetTradeRestrictions(); ResetSignalRestrictions(); ResetTradeWinRestrictions(); ResetTradeLoseRestrictions(); } /** * Resetting Signal Restrictions ... */ void ResetSignalRestrictions() { // mRestrictedSignals = 0; mRestrictedLongSignals = 0; mRestrictedShortSignals = 0; } /** * Resetting Trade Restrictions ... */ void ResetTradeRestrictions() { // mRestrictedTrades = 0; mRestrictedLongTrades = 0; mRestrictedShortTrades = 0; } /** * Resetting Trade Win Restrictions ... */ void ResetTradeWinRestrictions() { mWins = 0; mLongWins = 0; mShortWins = 0; } /** * Resetting Trade Lose Restrictions ... */ void ResetTradeLoseRestrictions() { // mLoses = 0; mLongLoses = 0; mShortLoses = 0; } // #endregion ... // // Private ... private: // // Props ... // // Last Restrictions Time ... datetime mLastCheck; // Last Restrictions Check ... datetime mRestrictionsEnd; // Last Restrictions End Time ... datetime mRestrictionsStart; // Last Restrictions Start Time ... // // Restrictions Period ... int mRestrictionsPeriodMultiplier; // Restrictions Period Multiplier ... ENUM_X_TRADE_RESTRICTIONS_PERIOD mRestrictionsPeriod; // Restrictions Period ... // #region Signals ... // int mSignals; // Issued Signals ... int mLongSignals; // Issued Long Signals ... int mShortSignals; // Issued Short Signals ... // int mRestrictedSignals; // Issued Signals in Restrictions Period ... int mRestrictedLongSignals; // Issued Long Signals in Restrictions Period ... int mRestrictedShortSignals; // Issued Short Signals in Restrictions Period ... // int mAllowedSignalsInRestrictions; // Allowed Signals in Restrictions Period ... int mAllowedLongSignalsInRestrictions; // Allowed Long Signals in Restrictions Period ... int mAllowedShortSignalsInRestrictions; // Allowed Short Signals in Restrictions Period ... // #endregion // #region Trades ... // int mTrades; // Executed Trades ... int mLongTrades; // Executed Long Trades ... int mShortTrades; // Executed Short Trades ... // int mRestrictedTrades; // Executed Trades in Restrictions Period ... int mRestrictedLongTrades; // Executed Long Trades in Restrictions Period ... int mRestrictedShortTrades; // Executed Short Trades in Restrictions Period ... // int mAllowedTradesInRestrictions; // Allowed Trades in Restrictions Period ... int mAllowedLongTradesInRestrictions; // Allowed Long Trades in Restrictions Period ... int mAllowedShortTradesInRestrictions; // Allowed Short Trades in Restrictions Period ... // #endregion // #region Wins ... // int mWins; // Touched Wins ... int mLongWins; // Touched Long Wins ... int mShortWins; // Touched Short Wins ... // int mRestrictedWins; // Touched Wins in Restrictions Period ... int mRestrictedLongWins; // Touched Long Wins in Restrictions Period ... int mRestrictedShortWins; // Touched Short Wins in Restrictions Period ... // int mAllowedWinsInRestrictions; // Allowed Wins in Restrictions Period ... int mAllowedLongWinsInRestrictions; // Allowed Long Wins in Restrictions Period ... int mAllowedShortWinsInRestrictions; // Allowed Short Wins in Restrictions Period ... // #endregion // #region Losess ... // int mLoses; // Touched Loses ... int mLongLoses; // Touched Long Loses ... int mShortLoses; // Touched Short Loses ... // int mRestrictedLoses; // Touched Loses in Restrictions Period ... int mRestrictedLongLoses; // Touched Long Loses in Restrictions Period ... int mRestrictedShortLoses; // Touched Short Loses in Restrictions Period ... // int mAllowedLosesInRestrictions; // Allowed Loses in Restrictions Period ... int mAllowedLongLosesInRestrictions; // Allowed Long Loses in Restrictions Period ... int mAllowedShortLosesInRestrictions; // Allowed Short Loses in Restrictions Period ... // #endregion // #region Event Handlers ... TRestrictionEvent mOnRestrictionsEndEventHandlers[]; // Restrictions End Event Handlers ... TRestrictionEvent mOnRestrictionsStartEventHandlers[]; // Restrictions Start Event Hnadlers ... // #endregion }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-rm.panel.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCRMPanel // Description: provides all based classes for use ... // // // 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.x-app-dialog.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5" // #include #include #include #include #include #include // // Implementation ... // class XCRMPanel : public XCAppDialog { // public: // // Event Binding ... // EVENT_MAP_BEGIN(XCRMPanel) // ON_EVENT(ON_CLICK, btnBuy, HandleBtnBuyClicked) // ON_EVENT(ON_CLICK, btnSell, HandleBtnSellClicked) // EVENT_MAP_END(XCRMPanel) // // Constructor(s) ... XCRMPanel() { // Default(); } // // Deconstructor ... ~XCRMPanel() { // HandleRemoveObjects(); // ZeroMemory(mTrader); } // // Props ... // int SubWindow() { return subWindow; } // void SubWindow(int value) { // if (value < 0) { value = 0; } // subWindow = value; } // // BUY ... // string BtnBuyLabel() { return buyLabelStr; } // void BtnBuyLabel(string value) { buyLabelStr = value; } // color BtnBuyBGColor() { return btnBuyBGColor; } // void BtnBuyBGColor(color value) { btnBuyBGColor = value; } // // SELL ... // string BtnSellLabel() { return sellLabelStr; } // void BtnSellLabel(string value) { sellLabelStr = value; } // color BtnSellBGColor() { return btnSellBGColor; } // void BtnSellBGColor(color value) { btnSellBGColor = value; } // double RiskPercent() { return riskPercent; } // void RiskPercent(double value) { // if (value < minAllowedRiskPercent) { value = minAllowedRiskPercent; } // if (value > maxAllowedRiskPercent) { value = maxAllowedRiskPercent; } // riskPercent = value; // tbRisk.Text((string)value); } // // // bool HasSL() { return slLine != NULL; } double ReadSL() { // double result = 0; // if (HasSL()) { // result = slLine.GetDouble(OBJPROP_PRICE); result = NormalizePrice(result, _Symbol); } // return result; } bool HasTP() { return tpLine != NULL; } double ReadTP() { // double result = 0; // if (HasTP()) { // result = tpLine.GetDouble(OBJPROP_PRICE); result = NormalizePrice(result, _Symbol); } // return result; } bool HasEntry() { return entryLine != NULL; } double ReadEntry() { // double result = 0; // if (HasEntry()) { // result = entryLine.GetDouble(OBJPROP_PRICE); result = NormalizePrice(result, _Symbol); } // return result; } bool GetDirection(ENUM_X_DIRECTION &dir) { // bool result = false; // dir = X_DIRECTION_NONE; // result = HasTP() && HasSL() && HasEntry(); // if (!result) { return result; } // double sl = ReadSL(); double tp = ReadTP(); double entry = ReadEntry(); // result = sl > 0 && tp > 0 && entry > 0; if (!result) { return result; } // bool isBullish = tp > entry && tp > sl && entry > sl; bool isBearish = tp < entry && tp < sl && entry < sl; result = isBullish || isBearish; if (!result) { return result; } // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Tools ... // void Default() { // string prefix = CreateInstanceId(); // defaultR2R = 2; riskPercent = 1; defaultRisk = 50; minAllowedRiskPercent = 0.5; maxAllowedRiskPercent = 10.0; // disabledBtnColor = clrLightGray; disabledBtnBGColor = clrGray; // tbRiskID = prefix + "_RiskTB"; // buyLabelStr = "Buy"; btnBuyBGColor = clrLime; btnBuyColor = clrDarkBlue; btnBuyID = prefix + "_" + buyLabelStr; // sellLabelStr = "Sell"; btnSellBGColor = clrRed; btnSellColor = clrDarkBlue; btnSellID = prefix + "_" + sellLabelStr; // slLine = NULL; slColor = clrMagenta; slID = prefix + "_SL"; // tpLine = NULL; tpColor = clrAqua; tpID = prefix + "_TP"; // entryLine = NULL; entryColor = clrYellow; entryID = prefix + "_Entry"; // btnDrawRemoveID = prefix + "_DrawRemove"; drawLabelStr = "Draw"; removeLabelStr = "Remove"; btnDrawColor = clrWhite; btnDrawBGColor = clrDarkBlue; btnRemoveColor = clrYellow; btnRemoveBGColor = clrDarkRed; // slippage = 10; magicNumber = 1694056; // // Create Trader Instance and Configure it ... mTrader = new XCTrade( slippage, magicNumber // ); } // void UpdateState() { // bool canEnable = HasSL() && HasTP() && HasEntry(); // if (canEnable) { SetRemoveMode(); } else { SetDrawMode(); } // double entry = GetBid(_Symbol); ENUM_X_DIRECTION dir; if (GetDirection(dir)) { entry = GetEntry(_Symbol, dir); } // if (HasEntry()) { double iEntry = ReadEntry(); if (iEntry != entry) { SetEntry(entry); } } } // // Handlers ... /** * Handle Btn Buy Clicked ... */ void HandleBtnBuyClicked() { // ENUM_X_DIRECTION dir; bool has = GetDirection(dir); bool isBullish = has & IsBullish(dir); if (!has || !isBullish) { return; } // double tp = ReadTP(); double sl = ReadSL(); double entry = ReadEntry(); // mTrader.Buy( _Symbol, _Period, volume, entry, sl, tp // ); } /** * Handle Btn Sell Clicked ... */ void HandleBtnSellClicked() { // ENUM_X_DIRECTION dir; bool has = GetDirection(dir); bool isBearish = has & IsBearish(dir); if (!has || !isBearish) { return; } // double tp = ReadTP(); double sl = ReadSL(); double entry = ReadEntry(); // mTrader.Sell( _Symbol, _Period, volume, entry, sl, tp // ); } /** * Handle Draw Remove Position ... */ void HandleBtnDrawRemoveClicked() { // string btnText = btnDrawRemove.Text(); if (btnText == drawLabelStr) { HandleDrawObjects(); } else if (btnText == removeLabelStr) { HandleRemoveObjects(); } } /** * Handle Risk Percent Changed ... */ void HandleOnRiskPercentChanged() { // string tbRiskStr = tbRisk.Text(); // double tbNewRisk = (double)tbRiskStr; RiskPercent(tbNewRisk); } // // Virtuals ... // virtual bool OnEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { // bool result = false; // XCAppDialog::OnEvent(id, lparam, dparam, sparam); // // Check if the event is a button click if (id == ON_CLICK + CHARTEVENT_CUSTOM) { // // Verify if the clicked object is this button if (lparam == btnBuy.Id()) { // HandleBtnBuyClicked(); result = true; } else if (lparam == btnSell.Id()) { // HandleBtnSellClicked(); result = true; } else if (lparam == btnDrawRemove.Id()) { // HandleBtnDrawRemoveClicked(); result = true; } } else if (id == ON_END_EDIT + CHARTEVENT_CUSTOM) { // if (lparam == tbRisk.Id()) { // HandleOnRiskPercentChanged(); result = true; } } else if (id == CHARTEVENT_OBJECT_DRAG) { // if (sparam == entryLine.Name()) { // CalculateData(); result = true; } else if (sparam == tpLine.Name()) { // CalculateData(); result = true; } else if (sparam == slLine.Name()) { // CalculateData(); result = true; } } // return result; } // // Overrides ... // bool Create( const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2 // ) { // bool result = false; // // Create App Dialog instance it Self ... result = XCAppDialog::Create( chart, name, subwin, x1, y1, x2, y2 // ); if (!result) { return result; } // chartId = chart; subWindow = subwin; // // Configure Dialog ... BackgroundColor(clrBlack); // int top = Top(); int left = Left(); int right = Right(); int bottom = Bottom(); // int width = Width(); int height = Height(); // int desiredWidth = width - left; int desiredHeight = height - top; // int btnWidth = desiredWidth / 2; int btnHeight = desiredHeight / 3; // // Risk Edit ... int tbRiskX1 = 0; int tbRiskY1 = 0; int tbRiskX2 = tbRiskX1 + (btnWidth * 2); int tbRiskY2 = tbRiskY1 + btnHeight; result = tbRisk.Create( chart, tbRiskID, subWindow, tbRiskX1, tbRiskY1, tbRiskX2, tbRiskY2 // ); if (!result) { return result; } // result = tbRisk.Text((string)riskPercent); result = tbRisk.TextAlign(ALIGN_CENTER); // result = Add(tbRisk); // // Create Draw/Remove Button ... int btnDrawX1 = 0; int btnDrawY1 = desiredHeight - (btnHeight * 2); int btnDrawX2 = btnDrawX1 + (btnWidth * 2); int btnDrawY2 = btnDrawY1 + btnHeight; result = btnDrawRemove.Create( chart, btnDrawRemoveID, subWindow, btnDrawX1, btnDrawY1, btnDrawX2, btnDrawY2 // ); if (!result) { return result; } // result = btnDrawRemove.Text(drawLabelStr); result = btnDrawRemove.Color(btnDrawColor); result = btnDrawRemove.ColorBackground(btnDrawBGColor); // result = Add(btnDrawRemove); // // Create Buy Button ... int btnBuyX1 = 0; int btnBuyY1 = desiredHeight - btnHeight; int btnBuyX2 = btnBuyX1 + btnWidth; int btnBuyY2 = btnBuyY1 + btnHeight; result = btnBuy.Create( chart, btnBuyID, subWindow, btnBuyX1, btnBuyY1, btnBuyX2, btnBuyY2 // ); if (!result) { return result; } // result = btnBuy.Text(buyLabelStr); result = btnBuy.Color(btnBuyColor); result = btnBuy.ColorBackground(btnBuyBGColor); // result = Add(btnBuy); // // Create Sell Button ... int btnSellX1 = btnBuyX2; int btnSellY1 = btnBuyY1; int btnSellX2 = btnSellX1 + btnWidth; int btnSellY2 = btnSellY1 + btnHeight; result = btnSell.Create( chart, btnSellID, subWindow, btnSellX1, btnSellY1, btnSellX2, btnSellY2 // ); if (!result) { return result; } // result = btnSell.Text(sellLabelStr); result = btnSell.Color(btnSellColor); result = btnSell.ColorBackground(btnSellBGColor); // result = Add(btnSell); // if (result) { // UpdateState(); CalculateData(); } // return result; } // protected: // XCTrade *mTrader; int slippage; long magicNumber; // long chartId; int subWindow; // string slID; color slColor; CChartObjectHLine *slLine; // string tpID; color tpColor; CChartObjectHLine *tpLine; // string entryID; color entryColor; CChartObjectHLine *entryLine; // double riskPercent; double minAllowedRiskPercent; double maxAllowedRiskPercent; // double volume; // double defaultR2R; double defaultRisk; // color disabledBtnColor; color disabledBtnBGColor; // // Risk Percent Edit ... CEdit tbRisk; string tbRiskID; // // BUY Button ... CButton btnBuy; string btnBuyID; string buyLabelStr; color btnBuyColor; color btnBuyBGColor; // // SELL Button ... CButton btnSell; string btnSellID; string sellLabelStr; color btnSellColor; color btnSellBGColor; // // DRAW / REMOVE Button ... CButton btnDrawRemove; string btnDrawRemoveID; string drawLabelStr; string removeLabelStr; color btnDrawColor; color btnDrawBGColor; color btnRemoveColor; color btnRemoveBGColor; // private: // bool EnableBuy(bool value) { // bool result = false; // btnBuy.Locking(!value); btnSell.Pressed(value); if (!value) { // // Disabled ... btnBuy.Color(disabledBtnColor); btnBuy.ColorBackground(disabledBtnBGColor); } else { // // Enable ... btnBuy.Color(btnBuyColor); btnBuy.ColorBackground(btnBuyBGColor); } // return result; } bool EnableSell(bool value) { // bool result = false; // btnSell.Locking(!value); btnSell.Pressed(value); if (!value) { // // Disabled ... btnSell.Color(disabledBtnColor); btnSell.ColorBackground(disabledBtnBGColor); } else { // // Enable ... btnSell.Color(btnSellColor); btnSell.ColorBackground(btnSellBGColor); } // return result; } bool SetDrawMode() { // bool result = false; // result = btnDrawRemove.Text(drawLabelStr); result = btnDrawRemove.Color(btnDrawColor); result = btnDrawRemove.ColorBackground(btnDrawBGColor); // return result; } bool SetRemoveMode() { // bool result = false; // result = btnDrawRemove.Text(removeLabelStr); result = btnDrawRemove.Color(btnRemoveColor); result = btnDrawRemove.ColorBackground(btnRemoveBGColor); // return result; } void HandleDrawObjects() { // double entry = GetBid(_Symbol); double points = GetPoints(_Symbol); double riskRatio = defaultRisk * points; double rewardRatio = riskRatio * defaultR2R; double sl = entry - riskRatio; double tp = entry + rewardRatio; // datetime rectTime1 = iTime( _Symbol, _Period, 20 // ); datetime rectTime2 = iTime( _Symbol, _Period, 19 // ); // bool has = false; // // Create Entry Line ... entryLine = new CChartObjectHLine(); has = entryLine.Create( chartId, entryID, subWindow, entry // ); if (!has) { // HandleRemoveObjects(); return; } entryLine.Selectable(false); entryLine.Color(entryColor); // // Create SL Line ... slLine = new CChartObjectHLine(); has = slLine.Create( chartId, slID, subWindow, sl // ); if (!has) { // HandleRemoveObjects(); return; } slLine.Color(slColor); slLine.Selectable(true); // // Create TP Line ... tpLine = new CChartObjectHLine(); has = tpLine.Create( chartId, tpID, subWindow, tp // ); if (!has) { // HandleRemoveObjects(); return; } tpLine.Color(tpColor); tpLine.Selectable(true); // CalculateData(); } void HandleRemoveObjects() { // if (HasSL()) { // slLine.Delete(); slLine.Detach(); ZeroMemory(slLine); } // if (HasTP()) { // tpLine.Delete(); tpLine.Detach(); ZeroMemory(tpLine); } // if (HasEntry()) { // entryLine.Delete(); entryLine.Detach(); ZeroMemory(entryLine); } // UpdateState(); CalculateData(); } void CalculateData() { // EnableBuy(false); EnableSell(false); // ENUM_X_DIRECTION dir; bool has = GetDirection(dir); if (!has) { return; } // bool isBullish = IsBullish(dir); bool isBearish = IsBearish(dir); // if (isBullish) { // EnableBuy(true); EnableSell(false); } else if (isBearish) { // EnableSell(true); EnableBuy(false); } // double sl = ReadSL(); double tp = ReadTP(); double entry = ReadEntry(); double points = GetPoints(_Symbol); // double risk = MathAbs(entry - sl); int riskPoints = (int)(risk / points); double riskRewardRatio = MathAbs(tp - entry) / risk; riskRewardRatio = NormalizeDouble(riskRewardRatio, 2); // double balance = GetBalance(); // double riskAmount = riskPercent * (balance / 100); riskAmount = NormalizePrice(riskAmount, _Symbol); // double rewardAmount = riskAmount * riskRewardRatio; rewardAmount = NormalizePrice(rewardAmount, _Symbol); // string currency = mTrader.mAccount.GetCurrency(); // volume = mTrader .mAccount .CalculateVolume( _Symbol, riskAmount, riskPoints // ); volume = NormalizeVolume(volume, _Symbol); // string slDesc = "SL: " + ToXString(sl) + ", Risk: " + ToXString(riskPoints) + " pt (" + ToXString(riskPercent) + "%)" + ", Amount: " + ToXString(riskAmount) + currency; slLine.Tooltip(slDesc); slLine.Description(slDesc); // string tpDesc = "TP: " + ToXString(tp) + " (" + ToXString(rewardAmount) + " " + currency + ")" + ", R2R: 1:" + ToXString(riskRewardRatio); tpLine.Tooltip(tpDesc); tpLine.Description(tpDesc); // string entryDesc = "Entry: " + ToXString(entry) + ", Volume: " + ToXString(volume); entryLine.Tooltip(entryDesc); entryLine.Description(entryDesc); // } void SetEntry(double value) { // if (value <= 0 || !HasEntry()) { return; } // bool has = entryLine .SetDouble(OBJPROP_PRICE, value); } double GetBalance() { // double result = 0; // // TODO: Change This ... return mTrader.mAccount.GetBalance(); // return result; } // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-signaller.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCBaseSignaller ... // Description: Base Signaller Class ... // // - Create an Instance based on this ... // - Attach Required Helpers for Indicator Usages ... // - Override Virtual Methdos: // - [] ProcessTick: Processing All Ticks // - [] ProcessNewBar: Processing All New Bars // - [] CheckForGuard: Check For Guards // - [] NormalizeSignal: Normalizing Prepared Signal ... // - [] CheckAdditionslSignallerValidations: Additional Class Validations // // - Dont Forget to Call OnSignal Event in Process Methods when // a signal Appears ... // // - also Whenever you want you can call PrepareSignal Action to // provide a Signal based on Current Market State ... // // 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 Base Signaller Class" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-market.pattern.class.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5" // // Definitions ... // // Implementations ... class XCBaseSignaller : public XCBase { // // Public ... public: // // Props ... string name; // Name ... string symbol; // Symbol ... ENUM_TIMEFRAMES period; // Period ... // bool ignoreTargets; // Ignore Signal Targets ... double slAdditionDistance; // SL Addition Distance ... double maxAllowedRiskDistance; // Max Allowed Risk In Points ... // // Restrictions ... datetime restUntil; // Resting Time ... int restingSignals; // Resting Signals ... datetime lastSignalAt; // Holding Last Signal's Time ... int restingDelay; // Resting Bars After Last Signal ... int loosingTrades; // Loosing Trades ... // TCanAnalyse canAnalyseEventListener; // XCMarketPatternDetector *patternDetector; // // Constructor ... XCBaseSignaller( string _name, // Name ... string _symbol, // Symbol ... ENUM_TIMEFRAMES _period, // Period ... bool _processAllTicks = false, // Process All Ticks ... double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... double _defaultSignalVolume = 0.01 // Default Signal Volume ... ) { // // Assign Properties ... name = _name; symbol = _symbol; period = _period; // ignoreTargets = false; slAdditionDistance = 0; maxAllowedRiskDistance = 0; // processAllTicks = _processAllTicks; defaultSignalR2R = _defaultSignalR2R; defaultSignalVolume = _defaultSignalVolume; defaultSignalRiskInPoint = _defaultSignalRiskInPoint; // // Normalize ... defaultSignalR2R = NormalizeDouble(defaultSignalR2R, 1, 10); defaultSignalVolume = NormalizeDouble(defaultSignalVolume, 0.01); defaultSignalVolume = NormalizeVolume(defaultSignalVolume, symbol, 2); defaultSignalRiskInPoint = NormalizeDouble(defaultSignalRiskInPoint, 10); // // Set Dfault Values ... mProcessedTicksCount = 0; mLastCheckedBarTime = NULL; // patternDetector = new XCMarketPatternDetector(); } // // Deconstructor ... ~XCBaseSignaller() { // // Cleanup Event Listeners ... SpecifiedClean(onSignalEventListeners); // delete patternDetector; ZeroMemory(patternDetector); } // // Event Listeners ... /** * Add On Signal Event Listener ... * * @param listener: TOnSignal instance ... */ void AddOnSignalEventHandler(TOnSignal listener) { // // Validate ... if (listener == NULL) { return; } // Add( listener, onSignalEventListeners // ); } // // Actions ... /** * Check Signaller Validation ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(name) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && // patternDetector != NULL && // CheckAdditionslSignallerValidations() // ; // return result; } /** * Handling On Tick Event ... * * @param barIndex: int, Specified Bar Index ... */ void OnTick(int barIndex = 0) { // // Normalize Bar Index ... if (barIndex < 0) { barIndex = 0; } // // Define Requirements ... XOHCL iBar; bool has = false; bool isNewBar = false; // // Get Current Bar Time ... datetime cBarTime = GetBarTime( symbol, period, barIndex // ); // // Validate Bar Time ... has = IsSpecifiedValid(cBarTime); if (!has) { return; } // // Check Rest Until ... has = !IsXValid(restUntil) || (IsXValid(restUntil) && cBarTime > restUntil); if (!has) { return; } // // Check Process Permissions ... has = CanAnalyseMarket(cBarTime); if (!has) { return; } // // Check if new Bar, Reset Processed Ticks Count ... isNewBar = cBarTime > mLastCheckedBarTime; if (isNewBar) { // mProcessedTicksCount = 0; ProcessNewBar(barIndex); return; } // // Check Allow Process ... // Process All Ticks ... // Process New Bars ... has = processAllTicks || (!processAllTicks && isNewBar); if (!has) { return; } // // Set Last Works ... mProcessedTicksCount++; mLastCheckedBarTime = cBarTime; // ProcessTick(barIndex); } // // Virtuals ... /** * Processing Tick ... * * @param barIndex: int, Specified Bar Index ... */ virtual void ProcessTick(int barIndex = 0) { } /** * Processing New Bar ... * * @param barIndex: int, Specified Bar Index ... */ virtual void ProcessNewBar(int barIndex = 0) { } /** * Check Guards Based on MarketConditions ... * * @param guards: XGuard, reference collection to holds result ... * @param positions: XPosition, reference collection to provides positions ... * @param barIndex: int * * @return ( int ) */ int virtual CheckForGuard( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ) { // int result = 0; // SpecifiedClean(guards); // result = ArraySize(guards); // return result; } /** * Check Additional Validations on Childs Instances ... * * @return ( bool virtual ) */ bool virtual CheckAdditionslSignallerValidations() { return true; } /** * Normalizing Signal by Signaller Custom Props ... * * @param signal: XSignal ... */ void virtual NormalizeSignal(XSignal &signal) { } /** * Prepare Restrictions Update For Losing Trades ... */ void LoseTrade() { // restingSignals++; loosingTrades++; } /** * Prepare Restrictions For Winning Trades ... */ void WinTrade() { // if (loosingTrades > 0) { loosingTrades--; } // if (restingSignals > 0) { restingSignals--; } } // // Protected ... protected: // // Props ... // bool processAllTicks; // Specified Processing All Ticks or not ... // int mProcessedTicksCount; // Prcoessed Ticks Count ... datetime mLastCheckedBarTime; // Last Checked Bar Time ... // double defaultSignalR2R; // Default Signal Risk To Reward Ratio ... double defaultSignalVolume; // Default Signal Volume ... double defaultSignalRiskInPoint; // Default Signal Risk In Point ... // // Event Notifiers ... /** * Notify OnSignal Event Listeners ... * * @param signal: XSignal, Specified Signal to Notify ... */ void NotifySignalEventListeners(XSignal &signal) { // int count = ArraySize(onSignalEventListeners); // // Validate ... if (!IsValidSize(count) || !signal.IsValid()) { return; } // // Check Restrictions ... if (HasRestrictions()) { // bool ignore = HandleRestrictions(signal); if (ignore) { return; } } // // Do Notify ... for (int i = 0; i < count; i++) { onSignalEventListeners[i](signal); } // lastSignalAt = signal.time; } /** * Calling Can Analyse Event Listeners ... * Check Can Analayse Market or not ... * * @param time: datetime, Specified Time for Checking ... * * @return ( bool ) */ bool CanAnalyseMarket(datetime time = NULL) { // bool result = false; // // Normalize ... time = NormalizeTime(time); // // Validation ... result = IsValid(); if (!result) { return result; } // result = canAnalyseEventListener == NULL; if (result) { return result; } // // Calling Can Analyse Event Listener ... result = canAnalyseEventListener( symbol, period, time // ); // return result; } /** * Preparing Default Signal ... * * @param signal: XSignal, holding result Signal ... * @param forDir: ENUM_X_DIRECTION * @param targets: XTarget Array, Provides Signal Targets (Price) ... * @param r2r: double, Provides Signal (r2r), if not Provided uses Default R2R ... * @param slPrice: double, Provides Signal SL Price, if not Provided uses riskInPoint ... * @param riskInPoint: double, Provides Signal Risk Amount which Multiplied to Points, if not Provided uses DefaultRiskInPoint ... * * @return ( bool ) */ bool PrepareSignal( XSignal &signal, ENUM_X_DIRECTION forDir, XTarget &targets[], // double r2r = 0, double slPrice = 0, double riskInPoint = 0 // ) { // bool result = false; // // Prepare ... signal.Clean(); // // Normalize ... // // Validate ... result = IsValid() && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsSpecifiedBullish(forDir); // double point = GetPoints(symbol); double spread = GetSpread(symbol); double volume = defaultSignalVolume; double entry = GetEntry(symbol, forDir); // riskInPoint = riskInPoint > 0 && slPrice <= 0 ? riskInPoint : defaultSignalRiskInPoint; double risk = (riskInPoint * point); risk = slPrice > 0 ? MathAbs(entry - slPrice) : risk; // r2r = r2r > 0 ? r2r : defaultSignalR2R; double reward = (risk * r2r) + spread; // double tp = isBullish ? entry + reward : entry - reward; // double sl = isBullish ? entry - risk : entry + risk; // // Filling Values ... signal.tp = tp; signal.sl = sl; signal.entry = entry; signal.provider = name; signal.symbol = symbol; signal.period = period; signal.volume = volume; signal.time = TimeCurrent(); signal.type = isBullish ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; signal.mode = X_ORDER_MODE_MARKET; // // Apply Targets ... if (HasChild(targets)) { // ApplyTargetsOnSignal( forDir, targets, signal // ); } // // Validate Signal ... result = signal.IsValid(); if (result) { // NormalizeSignal(signal); result = signal.IsValid(); } // if (!result) { signal.Clean(); } // return result; } /** * Check Signaller Has Restrictions or not ... * * @return ( bool ) */ bool HasRestrictions() { // bool result = false; // result = // // Rest Delay ... restingDelay > 0 || // // Resting Signals ... restingSignals > 0 || // // Rest Until ... IsXValid(restUntil) // ; // return result; } /** * Handle Restrictions On Signal ... * * @param signal: XSignal, reference to Provided Sginal ... * * @return ( bool ) */ bool HandleRestrictions(XSignal &signal) { // // Ignore Signal Execution ... bool result = true; // // Check Restrictions Exists ... if (!HasRestrictions()) { // // Disable Signal Ignoring and Allow Notify Signal ... result = false; return result; } // datetime cTime = TimeCurrent(); // // Resting Signals ... if (restingSignals > 0) { // restingSignals--; return result; } // // Rest Until ... if (IsXValid(restUntil)) { // if (cTime > restUntil) { // restUntil = NULL; // // Disable Signal Ignoring and Allow Notify Signal ... result = false; return result; } else { // // Ignore Signal ... return result; } } // // Resting Delay ... if (restingDelay > 0 && IsXValid(lastSignalAt)) { // int lastSignalIDX = GetBarIndex( signal.symbol, signal.period, lastSignalAt // ); if (IsValidIndex(lastSignalIDX)) { // if (lastSignalIDX > restingDelay) { // restingDelay = 0; // // Disable Signal Ignoring and Allow Notify Signal ... result = false; return result; } else { // // Ignore Signal ... return result; } } } // return result; } /** * Reset All Restrictions ... */ void ResetRestrictions() { // restingDelay = 0; restUntil = NULL; restingSignals = 0; } // // Private ... private: // // Props ... // // Event Listeners ... TOnSignal onSignalEventListeners[]; }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-target.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XCTarget // Description: provides all Positions Target requirements ... // // // 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-trade.class.mq5" // // Implementation ... class XCTarget : public XCBase { // // Public ... public: // XCTrade *trader; XCAlert *alert; XSignal signals[]; // // Constructor ... XCTarget( XCTrade *_trader, // XCAlert *_alert // ) : XCBase() { // alert = _alert; trader = _trader; // XClean(signals); } // // Deconstructor ... ~XCTarget() { Destroy(); } // void Destroy() { // XClean(signals); } // // Actions ... /** * Manage Positions ... * * @param barIndex: int, Bar Index ... */ void Manage(int barIndex = 0) { // // Normalize ... barIndex = NormalizeInt(barIndex, 0); // // Extract In Profit Positions ... XPosition positions[]; int count = GetInProfitPositions(positions); bool has = IsValidIndex(count); if (!has) { return; } // XSignal iSignal; XTarget iTarget; int signalIDX = -1; int targetIDX = -1; XPosition iPosition; // // Loop through Positions ... for (int i = 0; i < count; i++) { // // Select Positions ... iPosition = positions[i]; has = FindSignal( signalIDX, iPosition.ticket // ); if (!has) { continue; } iSignal = signals[signalIDX]; // // Selecting Target ... targetIDX = iSignal.appliedTargetIDX; if (iSignal.isTargetApplied) { targetIDX++; } // // Validate Targets Size ... has = HasChild(iSignal.targets) && targetIDX < ArraySize(iSignal.targets); if (has) { // // Select Target ... iTarget = iSignal.targets[targetIDX]; // // Check Can Apply Target and Apply it ... has = HandleApplyTarget(iTarget, iPosition); if (has) { // // Update Target IDX ... iSignal.appliedTargetIDX++; } } // // Update Signal ... signals[signalIDX] = iSignal; // // Cleanup ... iSignal.Clean(); iTarget.Clean(); iPosition.Clean(); } // // Cleanup Resources ... iSignal.Clean(); iTarget.Clean(); iPosition.Clean(); } /** * Extract in Profit Positions ... * * @param positions: XPosition, reference collection to holds result ... * * @return ( int ) */ int GetInProfitPositions( XPosition &positions[] // ) { // int result = 0; // // Prepare ... XClean(positions); // // Validate ... if (trader == NULL) { return result; } // result = trader.GetInProfitPositions( positions, NULL, // All Symbols ... NULL, // All Providers ... NULL, // All Periods ... NULL, // All Position Types ... X_POSITION_SELECT_ALL, // Select Method ... true, // Filter by Magic ... true // Force Clean ... ); if (IsValidSize(result)) { // XPosition iPos; XPosition tmp[]; Copy( positions, tmp // ); XClean(positions); while (HasChild(tmp)) { // iPos = tmp[0]; ArrayRemove( tmp, 0, 1 // ); // int idx = -1; bool has = FindSignal( idx, iPos.ticket // ); if (has) { // AddRef( iPos, positions // ); } } // XClean(tmp); iPos.Clean(); // result = ArraySize(positions); } // return result; } /** * Add Executed Signal ... * * @param signal: XSignal, reference to Executed Signal ... */ void AddExecutedSignal(XSignal &signal) { // // Validate ... if (!signal.IsValid() || !signal.IsExecuted()) { return; } // AddRef( signal, signals // ); } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnStopLossTriggered(const XDeal &deal) { RemoveSignal(deal.positionId); } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnTakeProfitTriggered(const XDeal &deal) { RemoveSignal(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 // ) { RemoveSignal(ticket); } // // Event Handlers Registration ... // void AddOnStopLossEventHandler(TOnStopLoss handler) { // if (handler == NULL) { return; } // Add( handler, mStopLossEventHandlers // ); } // void AddOnTakeProfitEventHandler(TOnTakeProfit handler) { // if (handler == NULL) { return; } // Add( handler, mTakeProfitEventHandlers // ); } // void AddOnForceClosePositionEventHandler(TOnForceClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnForceCloseEventHandlers // ); } // // Protected ... protected: // /** * Find Specified Signal ... * * @param index: int, reference to holds detected index ... * @param signal: XSignal, reference to Specified Signal ... * * @return ( bool ) */ bool FindSignal( int &index, XSignal &signal // ) { // bool result = false; // // Prepare ... index = -1; // // Validate ... result = signal.IsValid() && HasChild(signals); if (!result) { return result; } // // Looping Through Signals ... int count = ArraySize(signals); for (int i = 0; i < count; i++) { // result = signals[i] .IsSameAs(signal); if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Find Specified Signal ... * * @param index: int, reference to holds detected index ... * @param ticket: ulong, Specified Signal Position ID ... * * @return ( bool ) */ bool FindSignal( int &index, ulong ticket // ) { // bool result = false; // // Prepare ... index = -1; // // Validate ... result = NotEmptyZero(ticket) && HasChild(signals); if (!result) { return result; } // // Looping Through Signals ... int count = ArraySize(signals); for (int i = 0; i < count; i++) { // result = signals[i].IsValid() && signals[i].IsExecuted() && signals[i].positionId == ticket; if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Remove Specified Signal ... * * @param ticket: ulong, Specified Ticket ... */ void RemoveSignal(ulong ticket) { // bool has = NotEmptyZero(ticket) && HasChild(signals); if (!has) { return; } // int idx = -1; has = FindSignal( idx, ticket // ); if (!has) { return; } // ArrayRemove( signals, idx, 1 // ); } /** * Check Can Apply Specified Target on Specified Position or not ... * * @param target: XTarget, reference to Specified Target for Apply ... * @param position: XPosition, reference to Specified Position ... * * @return ( bool ) */ bool CanApplyTarget( XTarget &target, XPosition &position // ) { // bool result = false; // // Validate ... result = target.IsValid() && position.IsValid(); if (!result) { return result; } // // Check Price Reached Targets Value and Distance ... double targetDistance = (target.actingDistance > 0 ? target.actingDistance : 0) * position.GetPointsValue(); result = IsLong(position.type) ? position.price >= target.target + targetDistance : position.price <= target.target - targetDistance; // return result; } /** * Apply Specified Target on Specified Position ... * * @param target: XTarget, reference to Specified Target for Apply ... * @param position: XPosition, reference to Specified Position ... * * @return ( bool ) */ bool HandleApplyTarget( XTarget &target, XPosition &position // ) { // bool result = false; // // Validate ... result = target.IsValid() && position.IsValid() && CanApplyTarget( target, position // ); if (!result) { return result; } // // Apply Target ... string comment = NULL; string message = NULL; // // Do Risk Free if Provided ... if (result && target.doRF) { // comment = "Taregt Manager do RF ..."; result = trader.Modify( position.ticket, target.target, // SL ... position.tp, // TP ... comment // ); // // Handle Alert ... if (result) { // message = "Target Manager do RF " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") on: " + ToXString(position.price); alert.SendAlert(message); } } // // Do Risk Free on Entry if Provided ... if (result && target.doRFOnEntry) { // comment = "Target Manager do RF on Entry ..."; double actingDistance = position.GetPointsValue() * target.actingDistance; bool isLong = IsLong(position.type); double sl = position.entry + (isLong ? actingDistance : (-1 * actingDistance) // ); result = trader.Modify( position.ticket, sl, // SL ... position.tp, // TP ... comment // ); // // Handle Alert ... if (result) { // message = "Target Manager do RF " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") on Entry ..."; alert.SendAlert(message); } } // // Do Partial Close if Provided ... if (result && target.volumeMultiplier > 0) { // double volume = NormalizeVolume((position.volume * target.volumeMultiplier), position.symbol); if (volume != position.volume) { // comment = "Target Manager do Partial Close ..."; result = trader.ClosePartial( position.ticket, volume, comment // ); // // Handle Alert ... if (result) { // message = "Target Manager do Partial Close " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") by: " + ToXString(volume); alert.SendAlert(message); } } } // // Handle Replace TP ... if (result && target.tpValue > 0) { // // Validate TP Value ... bool isLong = IsLong(position.type); bool isValid = isLong ? target.tpValue > position.price && target.tpValue > position.tp : target.tpValue < position.price && target.tpValue < position.tp; if (isValid) { // comment = "Target Manager Change TP ..."; result = trader.Modify( position.ticket, position.sl, // SL ... target.tpValue, // TP ... comment // ); // // Handle Alert ... if (result) { // message = "Target Manager Change TP of" + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") to: " + ToXString(target.tpValue) + " ..."; alert.SendAlert(message); } } } // return result; } // // Private ... private: // // // Required Event Handlers ... TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-trade-manager.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XCXTradeManager // Description: provides all Trade Management requirements ... // // // 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.x-alert.class.mq5" #include "../Classes/x-saherelm.x-data.collector.class.mq5" #include "../Classes/x-saherelm.x-guard.class.mq5" #include "../Classes/x-saherelm.x-target.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5" #include "../Classes/x-saherelm.x-volume.class.mq5" // // Implementation ... class XCTradeManager : public XCBase { // // Public ... public: // // Props ... XCAlert *alert; XCGuard *guard; XCTrade *trader; XCTarget *target; XCVolume *volume; XTimeTracker timeTracker; XCDataCollector *collector; // XCPOIDrawer *drawer; // TCheckForGuard checkForGuardEventListener; // // Constructor ... XCTradeManager( XCAlert *_alert, XCTrade *_trader, XCVolume *_volume, XCGuard *_guard, XCTarget *_target // ) { // alert = _alert; guard = _guard; volume = _volume; trader = _trader; target = _target; // drawer = new XCPOIDrawer(); // allowTrade = true; allowLongs = true; allowShorts = true; // reportTrades = true; reportSignals = true; reportProtector = true; reportAfterTradesBalance = true; // SaveTrades(false); // collector = new XCDataCollector(); // // Setting Collector Path ... string mPath = (IsValid(alert.GetPrefix()) ? alert.GetPrefix() + "\\" : "") + trader.mAccount.GetCompany(); collector.Path(mPath); } // // Deconstructor ... ~XCTradeManager() { // Clean(trades); // timeTracker.Clean(); // delete drawer; ZeroMemory(drawer); // delete collector; ZeroMemory(collector); } // // Properties ... // bool SaveTrades() { return mSaveTrades; } // void SaveTrades(bool value) { mSaveTrades = value; } // bool SaveSignals() { return mSaveSignals; } // void SaveSignals(bool value) { mSaveSignals = value; } // bool SaveWins() { return mSaveWins; } // void SaveWins(bool value) { mSaveWins = value; } // bool SaveLosts() { return mSaveLosts; } // void SaveLosts(bool value) { mSaveLosts = value; } // bool SaveRestrictions() { return mSaveRestrictions; } // void SaveRestrictions(bool value) { mSaveRestrictions = value; } // // Setter(s) ... // void SetSymbolConfigurations(string symbolConfiguration) { // int count = 0; bool has = false; // // If Not Provided ... has = IsSpecifiedValid(symbolConfiguration); if (!has) { // AddDefaultSymbolConfiguration(); return; } // // Try to Parse Data ... string symbolData[]; count = SplitContent( symbolData, symbolConfiguration, "]" // ); has = IsValidSize(count); if (!has) { // AddDefaultSymbolConfiguration(); // SpecifiedClean(symbolData); return; } // // Loop through Exists Symbol Data's ... for (int i = 0; i < count; i++) { // string iData = symbolData[i]; // // Extract Data Parts ... string iParts[]; int iPartsCount = SplitContent( iParts, iData, "|" // ); has = IsValidSize(iPartsCount); if (has) { // // Determines Required Parts ... bool hasName = iPartsCount >= 1; bool hasSymbol = iPartsCount >= 2; bool hasPeriod = iPartsCount >= 3; bool hasSessionsDescriptor = iPartsCount >= 4; bool hasMaxAllowedSpred = iPartsCount >= 5; bool hasMaxAllowedPositios = iPartsCount >= 6; bool hasRestrictionDescriptor = iPartsCount >= 7; // // Parts IDX ... int partsIDX = 0; // // Extract Name ... string iName = hasName ? iParts[partsIDX] : ""; iName = EscapeString(iName); partsIDX++; // // Extract Symbol ... string iSymbol = hasSymbol ? iParts[partsIDX] : _Symbol; iSymbol = EscapeString(iSymbol); iSymbol = NormalizeSymbol(iSymbol); partsIDX++; // // Extract Period ... ENUM_TIMEFRAMES iPeriod = hasPeriod ? ToPeriod(EscapeString(iParts[partsIDX])) : _Period; iPeriod = NormalizePeriod(iPeriod); partsIDX++; // // Extract Sessions Descriptor ... string iSessionsDescriptor = hasSessionsDescriptor ? iParts[partsIDX] : ""; iSessionsDescriptor = EscapeString(iSessionsDescriptor); partsIDX++; // // Extract Max Allowed Sspread ... double iMaxAllowedSpread = hasMaxAllowedSpred ? (double)(EscapeString(iParts[partsIDX])) : 25; partsIDX++; // // Extract Max Allowedd Positions ... int iMaxAllowedPositions = hasMaxAllowedPositios ? (int)(EscapeString(iParts[partsIDX])) : 5; partsIDX++; // // Extract Restrictions Descriptor ... string iRestrictionsDescriptor = hasRestrictionDescriptor ? iParts[partsIDX] : ""; iRestrictionsDescriptor = EscapeString(iRestrictionsDescriptor); partsIDX++; // XSymbolTradeConfig iConfig; // // Initialize Config ... has = iConfig.Init( iName, iSymbol, iPeriod, iSessionsDescriptor, iMaxAllowedSpread, iMaxAllowedPositions, iRestrictionsDescriptor // ); if (has) { AddOrUpdateSymbolConfiguration(iConfig); } // // Cleanup Resources ... iConfig.Clean(); } // // Cleanup Resources ... SpecifiedClean(iParts); } // // Cleanup Resources ... SpecifiedClean(symbolData); } // int FillSymbolConfigurations(XSymbolTradeConfig &dest[]) { // SpecifiedClean(dest); // Copy( symbolTradeConfigs, dest // ); // int result = ArraySize(dest); // return result; } // void SetTradeReports( bool _reportTrades, bool _reportSignals, bool _reportProtector, bool _reportRestrictions, bool _reportAfterTradesBalance // ) { // reportTrades = _reportTrades; reportSignals = _reportSignals; reportProtector = _reportProtector; reportRestrictions = _reportRestrictions; reportAfterTradesBalance = _reportAfterTradesBalance; } // void SetTradePermissions( bool _allowTrade, bool _allowLongs, bool _allowShorts // ) { // allowTrade = _allowTrade; allowLongs = _allowLongs; allowShorts = _allowShorts; } // // Tools and Helpers ... /** * Do All Position Managing Senaros ... */ void Manage() { // // Handle Restrictions ... HandleRestrictions(); // // Managing Targets ... target.Manage(); // // Check Contains Trades for Managing ... bool has = HasChild(trades); if (!has) { return; } // // Update Required Infos of Trades ... int count = ArraySize(trades); for (int i = 0; i < count; i++) { // has = trades[i].IsExecuted() && !trades[i].IsFinalized(); if (!has) { continue; } // XPosition iPosition; has = trader.GetPosition( trades[i].positionID, iPosition // ); if (!has) { continue; } // // Update Trade Data ... trades[i].swap = iPosition.swap; trades[i].profit = iPosition.profit; } // // Do Trade Protection ... Protect(); } /** * Do All Position Protection Here ... */ void Protect() { // string prefix = "Protector: "; int targetDistance = 5; // bool has = HasChild(trades); if (!has) { return; } // XPosition ownPosition[]; XPosition ownLongPosition[]; XPosition ownShortPosition[]; // int count = ArraySize(trades); for (int i = 0; i < count; i++) { // has = trades[i].IsExecuted() && !trades[i].IsFinalized(); if (!has) { continue; } // XPosition iPosition; has = trader.GetPosition( trades[i].positionID, iPosition // ); if (!has) { continue; } // AddRef( iPosition, ownPosition // ); // if (IsLong(iPosition.type)) { // AddRef( iPosition, ownLongPosition // ); } else { // AddRef( iPosition, ownShortPosition // ); } } // has = HasChild(ownPosition); if (!has) { // Clean(ownPosition); Clean(ownLongPosition); Clean(ownShortPosition); // return; } // XGuard guards[]; int guardsCount = CheckForGuard(guards); bool hasGuard = IsValidSize(guardsCount); if (hasGuard) { // guard.DoGuards(guards); } // double swapSum = 0; double profitSum = 0; double commissionSum = 0; // // Calculate Required Data On Collection ... count = ArraySize(ownPosition); for (int i = 0; i < count; i++) { // XPosition iPosition = ownPosition[i]; // swapSum += iPosition.swap; profitSum += iPosition.profit; commissionSum += iPosition.commission; } // // Do Collection Protectiong ... // // Handle Force Close At Time ... has = HandleForceCloseAtTime(); if (has) { // Clean(ownPosition); Clean(ownLongPosition); Clean(ownShortPosition); // return; } // // Do Signle Protections ... for (int i = 0; i < count; i++) { // // Select Position ... XPosition iPosition = ownPosition[i]; int idx = -1; has = HasTrade( idx, iPosition.ticket // ); if (!has) { continue; } // bool isLong = IsLong(iPosition.type); double points = GetPoints(iPosition.symbol); // // Handle RF On Targets ... if (iPosition.profit > 0) { // // Handle Risk Free On Targets ... XTarget targets[]; Copy( trades[idx].signal.targets, targets // ); int targetsCount = ArraySize(targets); has = IsValidSize(targetsCount); if (has) { // for (int j = 0; j < targetsCount; j++) { // XTarget jTarget = targets[j]; // int appliedTargetIDX = -1; // // Check Target is Applied Before or Not ... has = !trades[idx].signal.isTargetApplied ? true : trades[idx].signal.appliedTargetIDX < j; if (!has) { continue; } // // Check Traget Validation ... has = iPosition.sl == 0 ? true : isLong ? iPosition.sl < jTarget.target : iPosition.sl > jTarget.target; if (!has) { continue; } // double targetDelta = isLong ? jTarget.target + (targetDistance * points) : jTarget.target - (targetDistance * points); // // Can Risk Free ... bool canRF = jTarget.doRF && jTarget.target > 0 && (isLong ? jTarget.target > iPosition.entry : jTarget.target < iPosition.entry) && (isLong ? iPosition.price > targetDelta : iPosition.price < targetDelta); // // Can Partial Close ... bool canPC = jTarget.volumeMultiplier > 0 && jTarget.target > 0 && (isLong ? jTarget.target > iPosition.entry : jTarget.target < iPosition.entry) && (isLong ? iPosition.price > targetDelta : iPosition.price < targetDelta); bool canRFPC = canRF || canPC; if (canRFPC) { // // Handle Risk Free ... bool isRFDone = false; if (canRF) { // double tp = iPosition.tp; double sl = jTarget.target; string comment = "RF On Target ..."; isRFDone = trader.Modify( iPosition.ticket, sl, tp, comment // ); } // // Handle Partail Close ... bool isPCDone = false; if (canPC) { // double _volume = jTarget.volumeMultiplier * iPosition.volume; _volume = NormalizeVolume(_volume, iPosition.symbol); string comment = "RF On Target ..."; isPCDone = trader.ClosePartial( iPosition.ticket, _volume, comment // ); } // // Handle Report Action ... bool isRFPCDone = isRFDone || isPCDone; if (isRFPCDone) { // trades[idx].signal.appliedTargetIDX = j; trades[idx].signal.isTargetApplied = true; // string message = prefix + ToXString(iPosition.type) + " Position: " + ToXString(iPosition.ticket) + (isRFDone ? " RF" : "") + (isPCDone ? " PC" : "") + " On Traget: " + ToXString(jTarget.target) + " Successfully ..."; HandleReportProtector(message); } } } } } } } /** * Check Can Analyse Market based on Configurations ... * * @param symbol: Symbol * @param period: Period * @param time: Analysing Time * * @return ( bool ) */ bool CanAnalyse( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { // bool result = false; // // Finding Symbol Configuration Index ... int idx = FindSymbolConfigurationIndex( symbol, period // ); // // If Not Exists ... if (!IsValidIndex(idx)) { // result = true; return result; } // // If Exists ... // // Check Session is Active ... result = symbolTradeConfigs[idx].CanTrade(time); if (!result) { return result; } // // Check Symbol Restrictions ... result = symbolTradeConfigs[idx].IsRestricted(time); if (!result) { return result; } // return result; } /** * Check Signal Execution Conditions ... * * @param signal: XSignal instance reference ... * @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ... * * @return ( bool ) */ bool CheckSignal( XSignal &signal, ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult // ) { // bool result = false; // // Cleanup ... executionResult = X_SIGNAL_EXECUTION_UNKNOWN; // // Validate Signal ... result = signal.IsValid(); if (!result) { return result; } // // Reporting Signal ... if (reportSignals) { // string message = signal.GetMessage("Provided"); alert.SendAlert(message); } // SaveSignal(signal); // // Check Trade Permission ... result = AllowTrade(signal.type); if (!result) { // result = false; executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; // return result; } // // Check Sessions and Restrictions ... result = CanAnalyse( signal.symbol, signal.period, signal.time // ); if (!result) { // executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED; // return result; } // // Check Signal Spread ... int idx = FindSymbolConfigurationIndex( signal.symbol, signal.period // ); if (IsValidIndex(idx)) { // double spread = GetSpread(signal.symbol); result = symbolTradeConfigs[idx].maxAllowedSpread > 0 ? spread <= symbolTradeConfigs[idx].maxAllowedSpread : true; if (!result) { // executionResult = X_SIGNAL_EXECUTION_FAILED_SPREAD; // return result; } // // Checking Max Allowed Positions ... if (symbolTradeConfigs[idx].maxAllowedPositions > 0) { // XPosition positions[]; ENUM_X_POSITION_TYPES mType = IsLong(signal.type) ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; int positionsCount = trader.GetPositions( positions, symbolTradeConfigs[idx].symbol, NULL, // All Providers ... symbolTradeConfigs[idx].period, mType, true, // Filter By Magic ... true // Force Clean ... ); result = !IsValidSize(positionsCount) || (IsValidSize(positionsCount) && positionsCount < symbolTradeConfigs[idx].maxAllowedPositions); // // Cleanup Resources ... SpecifiedClean(positions); } } // return result; } /** * Check Allow Trade or not .. * * @param type: ENUM_POSITIO_TYPE * * @return ( bool ) */ bool AllowTrade(ENUM_POSITION_TYPE type) { // bool result = false; // result = allowTrade; if (!result) { return result; } // result = (IsLong(type) && allowLongs) || (IsShort(type) && allowShorts); // return result; } /** * Execute Specified Signal ... * * @param signal: XSignal instance reference ... * @param conditions: XCATBEAStrategyConditions instance reference ... * * @return ( bool ) */ bool Execute(XSignal &signal) { // bool result = false; // result = signal.IsValid(); if (!result) { return result; } // int idx = -1; bool isExists = HasTrade( idx, signal // ); result = !isExists; if (!result) { return result; } // ENUM_X_SIGNAL_EXECUTION_RESULT executionResult; // // Checking Signal For Execution ... result = CheckSignal( signal, executionResult // ); if (result) { // result = trader.ExecuteSignal( signal, executionResult // ); } // // Alert Signal Execution ... if (reportTrades) { // string executionMessage = ToString(executionResult); // string message = NULL; if (result) { message = signal.GetMessage("Executed"); } else { message = signal.GetMessage("Failed due (" + executionMessage + ")"); } // alert.SendAlert(message); } // if (result) { // // Create Trade Struct ... XTradeInfo iTrade; // ulong positionID = trader.GetLastOpenPositionTicket(); double commission = trader.GetPositionCommission(positionID); // iTrade.signal = signal; iTrade.positionID = positionID; iTrade.commission = commission; iTrade.signaledAt = signal.time; iTrade.executedAt = TimeCurrent(); iTrade.conditions = signal.conditions; // AddRef( iTrade, trades // ); } // return result; } /** * Retrieve Specified Positions ... * * @param positions: XPosition instance Reference Array, which holds Founded Positions ... * @param symbol: string, Specified Symbol Name ... * @param provider: string, Specified Provider Name ... * @param period: ENUM_TIMEFRAMES, Specified Period ... * * @return ( int ) */ int GetPositions( XPosition &positions[], string symbol, string provider, ENUM_TIMEFRAMES period // ) { // int result = 0; // Clean(positions); // bool has = IsValid(symbol) && IsValid(period) && IsValid(provider); if (!has) { return result; } // result = trader.GetPositions( positions, symbol, provider, period, NULL, // All Types ... true, // Filter By Magic ... true // Force Clean ... ); // result = ArraySize(positions); // return result; } /** * Handle Signal Recieved ... * * @param signal: XSignal */ void HandleSignal(XSignal &signal) { // // Validate Signal ... if (!signal.IsValid()) { return; } // // Check Signal ... bool isExecuted = false; ENUM_X_SIGNAL_EXECUTION_RESULT signalExecutionResult; bool canExecute = CheckSignal( signal, signalExecutionResult // ); if (canExecute) { // HandleSignalVolume(signal); isExecuted = Execute(signal); } // // Draw Signal Object ... XCSignalObject *signalObj; bool has = drawer.DrawSignal( signal, signalObj, 4 // ); if (has) { mObjects.Add(signalObj); } } /** * Handle Position Take Profit ... * * @param deal: XDeal instance reference ... */ void HandleTP(const XDeal &deal) { // // Check Ticket Exists or not ... int idx = -1; bool isExists = HasTrade( idx, deal.positionId // ); if (!isExists) { return; } // // Apply Required Data ... trades[idx].swap = deal.swap; trades[idx].profit = deal.profit; trades[idx].finalizedAt = TimeCurrent(); trades[idx].finalize = XTRADE_FINAL_TP; // // Save Trade ... SaveWin(trades[idx]); SaveTrade(trades[idx]); // // Handle Balance Reporting ... string prefix = "TP: " + ToXString(trades[idx].profit); HandleReportBalance(prefix); // // Handle Symbol Config ... // int configIdx = FindSymbolConfigurationIndex( trades[idx].signal.symbol, trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) { // symbolTradeConfigs[configIdx].profits += 1; symbolTradeConfigs[configIdx].managedTPs += 1; symbolTradeConfigs[configIdx].managedProfits += trades[idx].profit; } // RemoveTrade(idx); // target.HandleOnTakeProfitTriggered(deal); } /** * Handle Position Stop Loss ... * * @param deal: XDeal instance reference ... */ void HandleSL(const XDeal &deal) { // // Check Ticket Exists or not ... int idx = -1; bool isExists = HasTrade( idx, deal.positionId // ); if (!isExists) { return; } // // Apply Required Data ... trades[idx].swap = deal.swap; trades[idx].profit = deal.profit; trades[idx].finalizedAt = TimeCurrent(); trades[idx].finalize = XTRADE_FINAL_SL; // // Save Trade ... SaveTrade(trades[idx]); // // Handle Balance Reporting ... string prefix = "SL: " + ToXString(trades[idx].profit); HandleReportBalance(prefix); // // Handle Symbol Info ... // bool isInProfit = trades[idx].profit > 0; if (isInProfit) { SaveWin(trades[idx]); } else { SaveLost(trades[idx]); } // // Handle Symbol Config ... // int configIdx = FindSymbolConfigurationIndex( trades[idx].signal.symbol, trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) { // if (isInProfit) { // symbolTradeConfigs[configIdx].profits += 1; symbolTradeConfigs[configIdx].managedTPs += 1; } else { // symbolTradeConfigs[configIdx].losses += 1; symbolTradeConfigs[configIdx].managedSLs += 1; } // symbolTradeConfigs[configIdx].managedProfits += trades[idx].profit; } // RemoveTrade(idx); // target.HandleOnStopLossTriggered(deal); } /** * Handle Position Force Close ... * * @param deal: XDeal instance reference ... */ void HandleForceClose(const XPosition &position) { // // Check Ticket Exists or not ... int idx = -1; bool isExists = HasTrade( idx, position.ticket // ); if (!isExists) { return; } // bool isInProfit = position.profit > 0; // // Apply Required Data ... trades[idx].swap = position.swap; trades[idx].profit = position.profit; trades[idx].finalizedAt = TimeCurrent(); trades[idx].commission = position.commission; trades[idx].finalize = isInProfit ? XTRADE_FINAL_CLOSE_IN_PROFIT : XTRADE_FINAL_CLOSE_IN_LOSE; // // Save Trade ... SaveTrade(trades[idx]); if (isInProfit) { SaveWin(trades[idx]); } else { SaveLost(trades[idx]); } // // Handle Balance Reporting ... string prefix = "Force Close " + (isInProfit ? "Profit" : "Loss") + ": " + ToXString(trades[idx].profit); HandleReportBalance(prefix); // // Handle Symbol Config ... // int configIdx = FindSymbolConfigurationIndex( trades[idx].signal.symbol, trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) { // if (isInProfit) { // symbolTradeConfigs[configIdx].profits += 1; symbolTradeConfigs[configIdx].managedTPs += 1; } else { // symbolTradeConfigs[configIdx].losses += 1; symbolTradeConfigs[configIdx].managedSLs += 1; } // symbolTradeConfigs[configIdx].managedProfits += trades[idx].profit; } // RemoveTrade(idx); // target.HandleOnPositionForceClosed( position.ticket, position, position.comment // ); } /** * Handle All Symbols Config Force Close At Time ... * * @return ( bool ) */ bool HandleForceCloseAtTime() { // bool result = false; // // Check Symbol Config Exists ... result = HasChild(symbolTradeConfigs); if (!result) { return result; } // result = false; int count = ArraySize(symbolTradeConfigs); for (int i = 0; i < count; i++) { // // Check Can Force Closed At ... bool has = IsSpecifiedValid(symbolTradeConfigs[i].closeAllOpenTradesAt); if (!has) { continue; } // // Parse Date ... datetime forceCloseTime = ParseDateTimeFromTimeString(symbolTradeConfigs[i].closeAllOpenTradesAt); has = IsTimeInRange( TimeCurrent(), forceCloseTime // ) && !symbolTradeConfigs[i].isForceCloseAtTime; if (!has) { continue; } // // Selecting Positions ... XTradeInfo iTrades[]; int iTradesCount = FillSymbolConfigurationTrades( symbolTradeConfigs[i], iTrades // ); has = IsValidSize(iTradesCount); if (!has) { // SpecifiedClean(iTrades); continue; } // // Converts Trades to Positions ... XPosition iPositions[]; int iPositionsCount = ToXPositions( iTrades, iPositions // ); has = IsValidSize(iPositionsCount); if (!has) { // SpecifiedClean(iTrades); SpecifiedClean(iPositions); continue; } // // Do Force Closing ... has = HandleForceCloseTrades(iPositions); if (has && !result) { result = true; } // // Cleanup Resources ... SpecifiedClean(iTrades); SpecifiedClean(iPositions); } // return result; } /** * Handle Position Partially Closed Event ... * * @param ticket: ULONG ... * @param profit: double ... * @param comment: string ... */ void HandlePartiallyClosed( const ulong ticket, const double profit, const string comment // ) { // // Handle Balance Reporting ... string prefix = "Partially Closed: " + ToXString(ticket); // // Handle Balance Reporting ... HandleReportBalance(prefix); } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void HandleGuardEvent( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { } /** * Handle Signal Executed Event ... * * @param signal: XSignal, reference to Executed Signal ... */ void HandleSignalExecuted(XSignal &signal) { target.AddExecutedSignal(signal); } // // Protected ... protected: // // Tools ... // string GetTradeFilePath(XTradeInfo &trade) { // string fileName = trade.GetFileName(); // return GetTradeFilePath(fileName); } // string GetTradeFilePath(string fileName) { // string result = NULL; // result = collector .GetFilePath("Trades" + "\\" + fileName); // return result; } // string GetSignalFilePath(string fileName) { // string result = NULL; // result = collector .GetFilePath("Signals" + "\\" + fileName); // return result; } // string GetWinsFilePath(XTradeInfo &trade) { // string result = NULL; // result = collector .GetFilePath("Conditions" + "\\" + trade.signal.symbol + "\\" + ToXString(trade.signal.period) + "_wins"); // return result; } // string GetLostsFilePath(XTradeInfo &trade) { // string result = NULL; // result = collector .GetFilePath("Conditions" + "\\" + trade.signal.symbol + "\\" + ToXString(trade.signal.period) + "_losts"); // return result; } // string GetRestrictionsFilePath(string symbol) { // string result = NULL; // if (!IsValid(symbol)) { return result; } // result = collector .GetFilePath("Restrictions" + "\\" + symbol); // return result; } // void HandleReportBalance(string prefix = NULL) { // if (!reportAfterTradesBalance) { return; } // double balance = trader.mAccount.GetBalance(); string currency = trader.mAccount.GetCurrency(); // string message = (IsValid(prefix) ? prefix + " | " : "") + "Account Balance: " + ToXString(balance) + currency; alert.SendAlert(message); } // void HandleReportProtector(string message = NULL) { // if (!reportProtector) { return; } // alert.SendAlert(message); } /** * Handle All Exists Symbol Configurations Restrictions ... */ void HandleRestrictions() { // // Count Symbol Configurations ... int count = ArraySize(symbolTradeConfigs); bool has = IsValidSize(count); if (!has) { return; } // // Handle Restrictions ... datetime cTime = TimeCurrent(); bool isNewDay = timeTracker.IsNewDay(); for (int i = 0; i < count; i++) { // // Reset Force Close At Time ... if (isNewDay) { symbolTradeConfigs[i].isForceCloseAtTime = false; } // // Handle Restrictions ... symbolTradeConfigs[i].HandleRestrictions(cTime); } } /** * Apply Signal Volume ... * * @param signal: XSignal */ void HandleSignalVolume(XSignal &signal) { // // Validate ... if (!signal.IsValid()) { return; } // // Handle Volume Management ... double iVolume = volume.CalculateVolume(signal); bool has = iVolume > X_MIN_VOLUME && iVolume != signal.volume; if (has) { signal.volume = iVolume; } // // Here we Can Implement Custom Signalling Volume Management // based on Different Symbol Configurations ... } /** * Handle Force Close Trades ... */ bool HandleForceCloseTrades( XPosition &positions[] // ) { // bool result = false; // result = HasChild(positions); if (!result) { return result; } // string prefix = "Protector: "; string comment = "Force Close ..."; // int count = ArraySize(positions); for (int i = 0; i < count; i++) { HandleForceClose(positions[i]); } // result = IsValidSize(count); if (result) { // string message = prefix + "Force Close (" + ToXString(count) + ") Trades at Specified Time ..."; HandleReportProtector(message); } // return result; } /** * Check For Guards ... * * @param dest: XGuard[] */ int CheckForGuard(XGuard &dest[]) { // int result = 0; // // Cleanup Dest ... SpecifiedClean(dest); // // Check For Guards ... if (checkForGuardEventListener != NULL) { // XPosition positions[]; trader.GetPositions(positions); result = checkForGuardEventListener(dest, positions, 0); } // result = ArraySize(dest); // return result; } // // Save Trades ... bool SaveTrade( XTradeInfo &trade, bool includeSummary = true, bool includeSignal = true, bool includeConditions = true // ) { // bool result = false; // if (!mSaveTrades) { return result; } // string filePath = GetTradeFilePath(trade); result = IsValid(filePath); if (!result) { return result; } // string content = trade.ToString( includeSummary, includeSignal, includeConditions // ); // result = collector.Save( filePath, content // ); // return result; } // // Save Signals ... bool SaveSignal(XSignal &signal) { // bool result = false; // // Check Signal Save is Enabled ... if (!mSaveSignals) { return result; } // // Check Signal Validation ... if (!signal.IsValid()) { return result; } // // Retrieve Signal File Name ... string signalFileName = signal.GetFileName(); result = IsValid(signalFileName); if (!result) { return result; } // // Retriev and Validate File Name ... string filePath = GetSignalFilePath(signalFileName); result = IsValid(filePath); if (!result) { return result; } // // Generate Content ... string content = ""; content += ToXString("----------------") + "\n" + ToXString("Signal: ") + "\n" + ToXString("----------------") + "\n" + signal.ToString() + "\n"; content += ToXString("----------------") + "\n" + ToXString("Conditions: ") + "\n" + ToXString("----------------") + "\n" + signal.conditions + "\n"; // // Save Content to File ... result = collector.Save( filePath, content // ); // // Return Result ... return result; } // bool SaveWin(XTradeInfo &trade) { // bool result = false; // if (!mSaveWins) { return result; } // string filePath = GetWinsFilePath(trade); result = IsValid(filePath); if (!result) { return result; } // // Preparing Conditions Content ... string content = trade.GetConditionsString(); // result = collector.Append( filePath, content // ); // return result; } // bool SaveLost(XTradeInfo &trade) { // bool result = false; // if (!mSaveLosts) { return result; } // string filePath = GetLostsFilePath(trade); result = IsValid(filePath); if (!result) { return result; } // // Preparing Conditions Content ... string content = trade.GetConditionsString(); // result = collector.Append( filePath, content // ); // return result; } // // Private ... private: // // Props ... // CArrayObj mObjects; // bool allowTrade; bool allowLongs; bool allowShorts; // bool mSaveWins; bool mSaveLosts; bool mSaveTrades; bool mSaveSignals; bool mSaveRestrictions; // bool reportTrades; bool reportSignals; bool reportProtector; bool reportRestrictions; bool reportAfterTradesBalance; // XTradeInfo trades[]; XSymbolTradeConfig symbolTradeConfigs[]; /** * Find Executed Trade by Providing Position Ticket ... * * @param index: int reference, holding founded item index ... * @param ticket: ulong, Specified Position Ticket ... * * @return ( bool ) */ bool HasTrade( int &index, ulong ticket // ) { // bool result = false; // index = -1; // result = ticket > 0 && HasChild(trades); if (!result) { return result; } // int count = ArraySize(trades); for (int i = 0; i < count; i++) { // XTradeInfo iTrade = trades[i]; // result = iTrade.HasSignal() && iTrade.IsExecuted() && iTrade.positionID == ticket; if (result) { // index = i; // iTrade.Clean(); break; } // iTrade.Clean(); } // result = IsValidIndex(index); // return result; } /** * Find Trade Item By Signal ... * * @param index: int reference, holding founded item index ... * * @return ( bool ) */ bool HasTrade( int &index, XSignal &signal // ) { // bool result = false; // index = -1; // result = signal.IsValid() && HasChild(trades); if (!result) { return result; } // int count = ArraySize(trades); for (int i = 0; i < count; i++) { // XTradeInfo iTrade = trades[i]; // result = iTrade.HasSignal() && iTrade.signal.IsSameAs(signal); if (result) { // index = i; // iTrade.Clean(); break; } // iTrade.Clean(); } // result = IsValidIndex(index); // return result; } /** * Remove a Trade From List ... * * @param index: int ... */ void RemoveTrade(int index) { // bool has = HasChild(trades) && IsValidIndex(index) && index < ArraySize(trades); if (!has) { return; } // ArrayRemove( trades, index, 1 // ); } // void AddOrUpdateSymbolConfiguration(XSymbolTradeConfig &config) { // // Check Validation ... bool has = config.IsValid(); if (!has) { return; } // // Check Index ... int idx = FindSymbolConfigurationIndex(config); has = IsValidIndex(idx); if (has) { // // Update Exists ... symbolTradeConfigs[idx] = config; } else { // // Add New ... AddRef( config, symbolTradeConfigs // ); } } // void AddDefaultSymbolConfiguration() { // // Define new Configuration ... XSymbolTradeConfig iConfig; // // Check Initialization ... bool has = iConfig.Init( "Default", _Symbol, _Period // ); // // Add Or Update ... if (has) { AddOrUpdateSymbolConfiguration(iConfig); } // // Clean Resources ... iConfig.Clean(); } // int FindSymbolConfigurationIndex(XSymbolTradeConfig &config) { // int result = -1; // if (!config.IsValid() || !SpecifiedHasChild(symbolTradeConfigs)) { return result; } // int count = ArraySize(symbolTradeConfigs); for (int i = 0; i < count; i++) { // if (symbolTradeConfigs[i].IsSame(config)) { // result = i; break; } } // return result; } // int FillSymbolConfigurationTrades( XSymbolTradeConfig &config, XTradeInfo &dest[] // ) { // int result = 0; // SpecifiedClean(dest); // // Check Trades ... int count = ArraySize(trades); if (!IsValidSize(count)) { return result; } // // Validate Config ... if (!config.IsValid()) { return result; } // // Find Config ... int idx = FindSymbolConfigurationIndex(config); if (!IsValidIndex(idx)) { return result; } // bool has = false; string symbol = symbolTradeConfigs[idx].symbol; ENUM_TIMEFRAMES period = symbolTradeConfigs[idx].period; for (int i = 0; i < count; i++) { // has = trades[i].signal.symbol == symbol && trades[i].signal.period == period && trades[i].positionID > 0; if (!has) { continue; } // AddRef( trades[i], dest // ); } // result = ArraySize(dest); // return result; } // int FindSymbolConfigurationIndex( string symbol, ENUM_TIMEFRAMES period // ) { // int result = -1; // // Validate Args ... if ( !IsSpecifiedValid(symbol) || !IsSpecifiedValid(period) || !HasChild(symbolTradeConfigs)) { return result; } // int count = ArraySize(symbolTradeConfigs); for (int i = 0; i < count; i++) { // if (symbolTradeConfigs[i].symbol == symbol && symbolTradeConfigs[i].period == period) { // result = i; break; } } // return result; } // // Tools ... // int ToXPositions( XTradeInfo &source[], XPosition &dest[] // ) { // int result = 0; // SpecifiedClean(dest); // int count = ArraySize(source); bool has = IsValidSize(count); if (!has) { return result; } // for (int i = 0; i < count; i++) { // XPosition iPosition; has = trader.GetPosition( source[i].positionID, iPosition); if (has) { // AddRef( iPosition, dest // ); } // iPosition.Clean(); } // result = ArraySize(dest); // return result; } // string EscapeString(string value) { // string result = value; // if (!IsSpecifiedValid(value)) { return result; } // StringReplace( result, "[", "" // ); // StringReplace( result, "]", "" // ); // StringReplace( result, "|", "" // ); // result = Trim(result); // return result; } }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-trade.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCTrade // Description: provides all Trade requirements ... // // // 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-account.class.mq5" #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5" // // Definitions ... // // Overrides ... // // XCTrade Base Class ... class XCTradeBase : public CTrade { public: // // Modify Specific Position, by Specific Comment ... bool PositionModify( const string symbol, // Symbol const double sl, // Stop Loss const double tp, // Take Profit const string comment = "" // Comment For Modify ) { // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // check position existence if (!SelectPosition(symbol)) { return (false); } // // clean ClearStructures(); // // setting request m_request.action = TRADE_ACTION_SLTP; m_request.symbol = symbol; m_request.magic = m_magic; m_request.sl = sl; m_request.tp = tp; m_request.position = PositionGetInteger(POSITION_TICKET); // // Specified Comment ... if (StringLen(comment) > 0) { m_request.comment = comment; } // // action and return the result return (OrderSend(m_request, m_result)); } bool PositionModify( const ulong ticket, // Position Ticket const double sl, // Stop Loss const double tp, // Take Profit const string comment = "" // Comment For Modify ) { // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // check position existence if (!PositionSelectByTicket(ticket)) { return (false); } // // clean ClearStructures(); // // setting request m_request.action = TRADE_ACTION_SLTP; m_request.position = ticket; m_request.symbol = PositionGetString(POSITION_SYMBOL); m_request.magic = m_magic; m_request.sl = sl; m_request.tp = tp; // // Specified Comment ... if (StringLen(comment) > 0) { m_request.comment = comment; } // // action and return the result return (OrderSend(m_request, m_result)); } // // Close Specific Position, by Specific Comment ... bool PositionClose( const string symbol, // Symbol const ulong deviation, // Deviation const string comment = "" // Comment For Close ) { // bool partial_close = false; int retry_count = 10; uint retcode = TRADE_RETCODE_REJECT; // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // clean ClearStructures(); // // check filling if (!FillingCheck(symbol)) { return (false); } // do { // // check if (SelectPosition(symbol)) { // if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { // // prepare request for close BUY position m_request.type = ORDER_TYPE_SELL; m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); } else { // // prepare request for close SELL position m_request.type = ORDER_TYPE_BUY; m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); } } else { // // position not found m_result.retcode = retcode; return (false); } // // setting request m_request.action = TRADE_ACTION_DEAL; m_request.symbol = symbol; m_request.volume = PositionGetDouble(POSITION_VOLUME); m_request.magic = m_magic; m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; m_request.position = PositionGetInteger(POSITION_TICKET); // // Specify Comment ... m_request.comment = comment; // // check volume double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); if (m_request.volume > max_volume) { // m_request.volume = max_volume; partial_close = true; } else { partial_close = false; } // // hedging? just send order if (IsHedging()) { return (OrderSend(m_request, m_result)); } // // order send if (!OrderSend(m_request, m_result)) { // if (--retry_count != 0) { continue; } // if (retcode == TRADE_RETCODE_DONE_PARTIAL) { m_result.retcode = retcode; } // return (false); } // //--- WARNING. If position volume exceeds the maximum volume allowed for deal, //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, //--- but partially. It is decreased by the maximum volume allowed for deal. if (m_async_mode) { break; } // retcode = TRADE_RETCODE_DONE_PARTIAL; if (partial_close) { Sleep(1000); } } while (partial_close); // // succeed return (true); } bool PositionClose( const ulong ticket, // Position Ticket const ulong deviation, // Deviation const string comment = "" // Comment For Close ) { // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // check position existence if (!PositionSelectByTicket(ticket)) { return (false); } // string symbol = PositionGetString(POSITION_SYMBOL); // // clean ClearStructures(); // // check filling if (!FillingCheck(symbol)) { return (false); } // // check if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { // // prepare request for close BUY position m_request.type = ORDER_TYPE_SELL; m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); } else { // // prepare request for close SELL position m_request.type = ORDER_TYPE_BUY; m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); } // // setting request m_request.action = TRADE_ACTION_DEAL; m_request.position = ticket; m_request.symbol = symbol; m_request.volume = PositionGetDouble(POSITION_VOLUME); m_request.magic = m_magic; m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; // // Specify Comment ... m_request.comment = comment; // // close position return (OrderSend(m_request, m_result)); } // // Partial Close Specific Position, by Specific Comment ... bool PositionClosePartial( const string symbol, // Symbol const double volume, // Partial Closing Volume const ulong deviation, // Deviation const string comment = "" // Comment For Close ) { // uint retcode = TRADE_RETCODE_REJECT; // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // for hedging mode only if (!IsHedging()) { return (false); } // // clean ClearStructures(); // // check filling if (!FillingCheck(symbol)) { return (false); } // // check if (SelectPosition(symbol)) { // if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { // // prepare request for close BUY position m_request.type = ORDER_TYPE_SELL; m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); } else { // // prepare request for close SELL position m_request.type = ORDER_TYPE_BUY; m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); } } else { // // position not found m_result.retcode = retcode; return (false); } // // check volume double position_volume = PositionGetDouble(POSITION_VOLUME); if (position_volume > volume) { position_volume = volume; } // // setting request m_request.action = TRADE_ACTION_DEAL; m_request.symbol = symbol; m_request.volume = position_volume; m_request.magic = m_magic; m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; m_request.position = PositionGetInteger(POSITION_TICKET); // // Specifieng Comment ... m_request.comment = comment; // // hedging? just send order return (OrderSend(m_request, m_result)); } bool PositionClosePartial( const ulong ticket, // Position Ticket const double volume, // Partial Closing Volume const ulong deviation, // Deviation const string comment = "" // Comment For Close ) { // // check stopped if (IsStopped(__FUNCTION__)) { return (false); } // // for hedging mode only if (!IsHedging()) { return (false); } // // check position existence if (!PositionSelectByTicket(ticket)) { return (false); } // string symbol = PositionGetString(POSITION_SYMBOL); // // clean ClearStructures(); // // check filling if (!FillingCheck(symbol)) { return (false); } // // check if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { // // prepare request for close BUY position m_request.type = ORDER_TYPE_SELL; m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); } else { // // prepare request for close SELL position m_request.type = ORDER_TYPE_BUY; m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); } // // check volume double position_volume = PositionGetDouble(POSITION_VOLUME); if (position_volume > volume) { position_volume = volume; } // // setting request m_request.action = TRADE_ACTION_DEAL; m_request.position = ticket; m_request.symbol = symbol; m_request.volume = position_volume; m_request.magic = m_magic; m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; // // Specifieng Comment ... m_request.comment = comment; // // close position return (OrderSend(m_request, m_result)); } }; // // Implementation ... // // a Class For Manage Trades and Handle Trading Actions ... class XCTrade : public XCBase { // // Public ... public: // // Props ... XCAccount *mAccount; // Account Info Provider // // Constructors ... XCTrade( int slippage, // Specify Slippage ulong magicNumber, // Specify Magic Number double maxAllowedSpread = 0, // Max Allowed Spred for Opening Trades int maxAllowedPositions = 0, // Max Allowed Positions double maxAllowedDrawdownFactor = 0 // Max Allowed Drawdown Factor ) { // // Setting Props ... mSlippage = slippage; mMagicNumber = magicNumber; // mMaxAllowedSpread = maxAllowedSpread; mMaxAllowedPositions = maxAllowedPositions; mMaxAllowedDrawdownFactor = maxAllowedDrawdownFactor; // mAccount = new XCAccount(); // // Instance Base Trader Class ... mTrader = new XCTradeBase(); // // Configuring Base Trader Class ... mTrader.SetAsyncMode(false); mTrader.SetDeviationInPoints(mSlippage); mTrader.SetExpertMagicNumber(mMagicNumber); // // Setting Log Level ... mTrader.LogLevel(LOG_LEVEL_ERRORS); // // OnTrade Context ... // mDaysForRead = 1; mScanStarted = false; // // Reset On Trade Counter ... ResetOnTradeContext(); // // Init On Trade Context ... InitOnTradeContext(); } // // Deconstructor ... ~XCTrade() { // // Remove Pointer ... delete mTrader; delete mAccount; // ZeroMemory(mTrader); ZeroMemory(mAccount); // Clean(mOnModifyEventHandlers); Clean(mStopLossEventHandlers); Clean(mTakeProfitEventHandlers); Clean(mOnForceCloseEventHandlers); Clean(mDealsChangedEventHandlers); Clean(mOrdersChangedEventHandlers); Clean(mOnPartialCloseEventHandlers); Clean(mPositionsChangedEventHandlers); Clean(mTradeStateChangedEventHandlers); } // // Props ... // // Retrieve Slippage ... int GetSlippage() { return mSlippage; } // // Retrieve Magic Number ... ulong GetMagicNumber() { return mMagicNumber; } // double GetMaxAllowedSpread() { return mMaxAllowedSpread; } // int GetMaxAllowedPositions() { return mMaxAllowedPositions; } // void SetMaxAllowedPositions(int value) { // if (value < 0) { value = 0; } // mMaxAllowedPositions = value; } // double GetMaxAllowedDrawdownFactor() { return mMaxAllowedDrawdownFactor; } // // Add Event Listeners ... // void AddOnModifyPositionEventHandler(TOnModify handler) { // if (handler == NULL) { return; } // Add( handler, mOnModifyEventHandlers // ); } // void AddOnForceClosePositionEventHandler(TOnForceClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnForceCloseEventHandlers // ); } // void AddOnPartialClosePositionEventHandler(TOnPartialClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnPartialCloseEventHandlers // ); } // // Add New Deals Changed Event Handler ... void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) { // if (handler == NULL) { return; } // Add( handler, mTradeStateChangedEventHandlers // ); } // // Add New Deals Changed Event Handler ... void AddOnDealsChangedEventHandler(TOnDealsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mDealsChangedEventHandlers // ); } // // Add New Orders Changed Event Handler ... void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) { // if (handler == NULL) { return; } // Add( handler, mOrdersChangedEventHandlers // ); } // // Add New Positions Changed Event Handler ... void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mPositionsChangedEventHandlers // ); } // // Add New Stop Loss Event Handler ... void AddOnStopLossEventHandler(TOnStopLoss handler) { // if (handler == NULL) { return; } // Add( handler, mStopLossEventHandlers // ); } // // Add New Stop Loss Event Handler ... void AddOnTakeProfitEventHandler(TOnTakeProfit handler) { // if (handler == NULL) { return; } // Add( handler, mTakeProfitEventHandlers // ); } // // Add New Signal Executed Event Handler ... void AddOnSignalExecutedEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalExecutedEventHandlers // ); } // // Functions ... // // Handlers ... // // Process On Trade Requirement ... // this Only Used when we Have to Proccess OnTrade Event in EA(s) ... void HandleOnTradeEvent( XOnTradeHandlerState &result // Hold's Result ) { // result.Clean(); // if (mScanStarted) { // ProcessOnTradeContext(result); } else { // // Init Trade Context ... InitOnTradeContext(); // return; } // // Here we Can Check the Start ... bool isValid = // result.IsValid() && // !result.hasNewDeal && !result.hasNewOrder && !result.hasNewPosition && !result.hasNewHistoryOrder // ; if (!isValid) { return; } // // State ... // // Notfy Trade State Changed Event ... NotifyTradeStateChangeEvent(result); // // Deals ... if (result.hasNewDeal) { // // Notfy Deals Changed Event ... NotifyDealsChangeEvent(result.newDeals); // // Retrieve Last Deal ... XDeal deals[]; int dealsCount = GetDeals(deals); if (dealsCount > 0) { // XDeal lastDeal = deals[0]; // if (lastDeal.reason == DEAL_REASON_TP) { NotifyTakeProfitEvent(lastDeal); } else if (lastDeal.reason == DEAL_REASON_SL) { NotifyStopLossEvent(lastDeal); } } } // // Orders ... if (result.hasNewOrder || result.hasNewHistoryOrder) { // // Notfy Orders Changed Event ... NotifyOrdersChangeEvent(result.newOrders + result.newHistoryOrders); } // // Positions ... if (result.hasNewPosition) { // // Notfy Positions Changed Event ... NotifyPositionsChangeEvent(result.newPositions); } } // // This Must be Called Every time OnTrade Event Happening ... // this Used for Implementing Custom Senarios ... XOnTradeHandlerState HandleOnTrade() { // // Handle OnTrade Event ... XOnTradeHandlerState state; HandleOnTradeEvent(state); if ( !state.hasNewDeal && !state.hasNewOrder && !state.hasNewPosition && !state.hasNewHistoryOrder) { return state; } // // State ... // // Notfy Trade State Changed Event ... NotifyTradeStateChangeEvent(state); // // DEALS ... if (state.hasNewDeal) { // // Notfy Deals Changed Event ... NotifyDealsChangeEvent(state.newDeals); // // Retrieve Last Deal ... XDeal deals[]; GetDeals(deals); int dealsCount = ArraySize(deals); if (dealsCount > 0) { // XDeal lastDeal = deals[0]; // if (lastDeal.reason == DEAL_REASON_TP) { NotifyTakeProfitEvent(lastDeal); } else if (lastDeal.reason == DEAL_REASON_SL) { NotifyStopLossEvent(lastDeal); } } } // // ORDERS ... if (state.hasNewOrder || state.hasNewHistoryOrder) { // // Notfy Orders Changed Event ... NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); } // // POSITIONS ... if (state.hasNewPosition) { // // Notfy Positions Changed Event ... NotifyPositionsChangeEvent(state.newPositions); } // return state; } // // Trade Actions ... // // Main ... // // Policies ... // // Check Acocunt Balance is Allow new Trades or not ... bool CheckEquityForTrade() { // bool result = false; // if (mMaxAllowedDrawdownFactor <= 0) { // result = true; return result; } // double equity = mAccount.GetEquity(); double balance = mAccount.GetBalance(); // double selectedBalance = MathMax(equity, balance) - MathMin(equity, balance); // double maxAllowedBalanceDrawDown = GetMaxAllowedEquity(); // result = equity > balance || (equity <= balance && selectedBalance <= maxAllowedBalanceDrawDown); // return result; } // // Check Max Allowed Positions Policy for Trade ... bool CheckPositionsForTrade() { // bool result = false; // if (mMaxAllowedPositions <= 0) { // result = true; return result; } // XPosition positions[]; int positionsCount = GetPositions(positions); if (positionsCount <= 0) { // result = true; return result; } // result = positionsCount < mMaxAllowedPositions; // return result; } // // Check Spread is Ok for Executing Specific Signal ... bool CheckSpreadForSignalExecution(XSignal &mSignal) { // bool result = false; // bool isSpreadCheckEnable = mMaxAllowedSpread > 0; if (!isSpreadCheckEnable) { result = true; } else { // // Retrieve Signal Spread ... double spread = GetSpread(mSignal.symbol); result = spread <= mMaxAllowedSpread; } // return result; } // // Check Account Policy ... bool CheckAccountPolicy( XSignal &mSignal, // For Executing Signal ENUM_X_SIGNAL_EXECUTION_RESULT &state // State Holder ) { // bool result = false; // // Check Positions For Trade ... result = CheckPositionsForTrade(); if (!result) { // state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; return result; } // // Check Equity For Trade ... result = CheckEquityForTrade(); if (!result) { // state = X_SIGNAL_EXECUTION_FAILED_NO_EQUITY; return result; } // // Check Spread for Trade ... result = CheckSpreadForSignalExecution(mSignal); if (!result) { // state = X_SIGNAL_EXECUTION_FAILED_SPREAD; return result; } // return result; } // // Execute a Signal ... bool ExecuteSignal( XSignal &mSignal, // Signal ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime datetime expiration = NULL, // order expiration time bool checkPolicies = true // Check Account Policies ) { // bool result = false; state = X_SIGNAL_EXECUTION_UNKNOWN; // double currentEntry = GetEntry( mSignal.symbol, mSignal.type // ); bool isLong = IsLong(mSignal.type); // if (!mSignal.IsValid()) { // state = X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS; return result; } // // Prepare Signal Comment ... string mSComment = mSignal.GenerateComment(); if (!Contains(mSComment, mSignal.comment)) { mSignal.comment += mSComment; } // // Handle Market Execution ... if (mSignal.mode == X_ORDER_MODE_MARKET) { // // Do Apply Policies here ... bool hasPolicy = !checkPolicies ? true : CheckAccountPolicy(mSignal, state); if (!hasPolicy) { result = false; } else { // if (isLong) { // result = Buy( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, mSignal.comment // ); } else { // result = Sell( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, mSignal.comment // ); } } } // // Handle Stop Execution ... else if (mSignal.mode == X_ORDER_MODE_STOP) { // // Check Conditions ... // // Check Price ... result = isLong ? mSignal.entry > currentEntry : mSignal.entry < currentEntry; if (!result) { // state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; return result; } // // Execute Order ... if (isLong) { // result = BuyStop( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, lifetime, expiration, mSignal.comment // ); } else { // result = SellStop( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, lifetime, expiration, mSignal.comment // ); } } // // Handle Limit Execution ... else if (mSignal.mode == X_ORDER_MODE_LIMIT) { // // Check Conditions ... // // Check Price ... result = isLong ? mSignal.entry < currentEntry : mSignal.entry > currentEntry; if (!result) { // state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; return result; } // // Execute Order ... if (isLong) { // result = BuyLimit( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, lifetime, expiration, mSignal.comment // ); } else { // result = SellLimit( mSignal.symbol, mSignal.period, mSignal.volume, mSignal.entry, mSignal.sl, mSignal.tp, lifetime, expiration, mSignal.comment // ); } } // // Handle Ticket ... if (result) { // state = X_SIGNAL_EXECUTION_SUCCEED; // ulong ticket; if (mSignal.mode == X_ORDER_MODE_MARKET) { ticket = GetLastOpenPositionTicket(); } else { ticket = GetLastPlacedOrderTicket(); } // mSignal.positionId = ticket; // // Notify Signal Execution ... if (mSignal.mode == X_ORDER_MODE_MARKET) { NotifySignalExecuted(mSignal); } } // return result; } // // Execute a Collection Of Signals ... int ExecuteSignals( XSignal &signals[], // Collection of Signal for Execution ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime datetime expiration = NULL, // order expiration time bool checkPolicies = true // Check Account Policies ) { // int result = 0; // Clean(states); // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return result; } // ArrayResize(states, signalsCount); ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); for (int i = 0; i < signalsCount; i++) { // bool isExecuted = ExecuteSignal( signals[i], states[i], lifetime, expiration, checkPolicies // ); // if (isExecuted) { result++; } } // return result; } // int ExecuteSpecifiedSignals( XSignal &signals[], // Collection of Signal for Execution XSignal ¬Executeds[], // Not Executed Signal ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime datetime expiration = NULL, // order expiration time bool checkPolicies = true // Check Account Policies ) { // int result = 0; // Clean(states); Clean(notExecuteds); // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return result; } // ArrayResize(states, signalsCount); ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); for (int i = 0; i < signalsCount; i++) { // bool isExecuted = ExecuteSignal( signals[i], states[i], lifetime, expiration // ); // if (isExecuted) { result++; } else { // AddRef( signals[i], notExecuteds // ); } } // return result; } // // Regular Trade Actions ... // // Buy ... // // Force Open a Buy/Long Position ... bool Buy( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // position volume double price, // execution price double sl = 0, // stop loss price double tp = 0, // take profit price string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.Buy( volume, symbol, price, sl, tp, comment // ); // return result; } // // Send BUY LIMIT order ... bool BuyLimit( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // order volume double price, // order price double sl = 0.0, // stop loss price double tp = 0.0, // take profit price ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime datetime expiration = 0, // order expiration time string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.BuyLimit( volume, price, symbol, sl, tp, typeTime, expiration, comment // ); // return result; } // // Send BUY STOP order ... bool BuyStop( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // order volume double price, // order price double sl = 0.0, // stop loss price double tp = 0.0, // take profit price ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime datetime expiration = 0, // order expiration time string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.BuyStop( volume, price, symbol, sl, tp, typeTime, expiration, comment // ); // return result; } // // Sell ... // // Force Open a Sell/Short Position ... bool Sell( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // position volume double price, // execution price double sl = 0, // stop loss price double tp = 0, // take profit price string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.Sell( volume, symbol, price, sl, tp, comment // ); // return result; } // // Send SELL LIMIT order ... bool SellLimit( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // order volume double price, // order price double sl = 0.0, // stop loss price double tp = 0.0, // take profit price ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime datetime expiration = 0, // order expiration time string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.SellLimit( volume, price, symbol, sl, tp, typeTime, expiration, comment // ); // return result; } // // Send SELL STOP order ... bool SellStop( string symbol, // Specified Symbol ENUM_TIMEFRAMES period, // Specified Trade's Period double volume, // order volume double price, // order price double sl = 0.0, // stop loss price double tp = 0.0, // take profit price ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime datetime expiration = 0, // order expiration time string comment = NULL // comment ) { // bool result = false; // ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); if (!IsValid(comment) || !IsValid(mPeriod)) { // string mPeriodStr = GeneratePeriodTag(period); // comment += mPeriodStr; } // result = mTrader.SellStop( volume, price, symbol, sl, tp, typeTime, expiration, comment // ); // return result; } // // Check a Position is Exists Open or not ... bool IsOpen( ulong ticket // Specified Position Ticket ) { // bool result = false; // result = mPositionInfo .SelectByTicket(ticket); // return result; } // // Modify Position ... bool Modify( const ulong ticket, // position ticket double sl = 0, // stop loss price double tp = 0, // take profit string comment = NULL // comment ) { // bool result = false; // // Validate Args ... XPosition position; result = GetPosition( ticket, position // ) && (tp >= 0 || sl >= 0); if (!result) { return result; } // // Use Position Comment when there isn't new One ... if (!IsValid(comment) == 0) { // // if there isn't provided Comment // Use Position Comment for default ... comment = "Modify " + GetPositionComment(ticket); } // result = mTrader.PositionModify( ticket, sl, tp, comment // ); if (result) { // NotifyModifyEvent( ticket, position.profit, comment // ); } // return result; } // // Close Position By Ticket ... bool Close( ulong ticket, // Position Ticket string comment = NULL // Close Position By Specific Comment ) { // bool result = false; // // Check Position Open ... XPosition position; result = GetPosition( ticket, position // ); if (!result) { return result; } // // Use Default Position Comment if it's Not Provided ... if (!IsValid(comment)) { comment = "Close " + GetPositionComment(ticket); } // // Close Position By Specific Comment ... result = mTrader.PositionClose( ticket, mSlippage, comment // ); if (result) { // NotifyForceCloseEvent( ticket, position, comment // ); } // return result; } // // Close Specified Positions ... int Close( string comment = NULL, // Close Position By Specific Comment string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) bool filterByMagic = true // Get Only Self Open Positions ) { // int result = 0; // XPosition positions[]; int positionsCount = GetPositions( positions, symbol, provider, period, type, filterByMagic); if (positionsCount <= 0) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // bool isClosed = Close( iPosition.ticket, comment // ); if (isClosed) { result++; } } // return result; } // // Close a Collection of Positions ... int Close( XPosition &positions[], // Collection of Positions string comment = NULL // Close Comment ) { // int result = 0; // int positionsCount = ArraySize(positions); if (positionsCount <= 0) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // bool isClosed = Close( iPosition.ticket, comment // ); if (isClosed) { result++; } } // return result; } // // Close Partial By Ticket ... bool ClosePartial( ulong ticket, // Position Ticket double volume, // Volume Size for Partial Closing string comment = NULL // Close Position By Specific Comment ) { // bool result = false; // XPosition position; result = GetPosition( ticket, position // ); if (!result) { return result; } // // Use Default Partial Close Comment ... if (!IsValid(comment)) { // comment += "PClose " + GetPositionComment(ticket); } // result = mTrader.PositionClosePartial( ticket, volume, mSlippage, comment // ); if (result) { // NotifyPartialCloseEvent( ticket, position.profit, comment // ); } // return result; } // // Cancel Specific Order ... bool CancelOrder(ulong ticket) { return mTrader .OrderDelete(ticket); } // // Cancel Specific Orders ... int CancelOrders( XOrder &orders[] // Specified Orders ... ) { // int result = 0; // int ordersCount = ArraySize(orders); if (ordersCount <= 0) { return result; } // for (int i = 0; i < ordersCount; i++) { // XOrder iOrder = orders[i]; // bool isDeleted = mTrader .OrderDelete(iOrder.ticket); if (isDeleted && !result) { result++; } } // return result; } // // Extractors ... // // Positions ... // // Calculate Positions Profit ... double Profit( string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) bool filterByMagic = true // Get Only Self Open Positions ) { // double result = 0; // // Retrieve Positions ... XPosition positions[]; int positionsCount = GetPositions( positions, symbol, provider, period, type, filterByMagic // ); if (positionsCount <= 0) { return result; } // for (int i = 0; i < positionsCount; i++) { result += positions[i].profit; } // return result; } // // Retrieve Specific Position by Index ... bool GetPositionByIndex( int index, // Specified Index XPosition &result // Hold's Result ) { // bool isInited = result .ByIndex(index); // return isInited; } // // Retrieve Specific Position by Ticket ... bool GetPosition( ulong ticket, // Specified Ticket XPosition &result // Hold's Result ) { // bool isInited = result .ByTicket(ticket); // return isInited; } // double GetPositionCommission( ulong ticket // Specified Ticket ) { // double result = 0; // XPosition position; bool hasPosition = GetPosition( ticket, position // ); if (!hasPosition) { return result; } // XDeal deals[]; int dealsCount = GetDeals( deals, position.symbol, position.provider, position.period, NULL, DEAL_ENTRY_IN // ); if (IsValidSize(dealsCount)) { // for (int i = 0; i < dealsCount; i++) { // XDeal iDeal = deals[i]; if (iDeal.positionId == ticket) { // result = iDeal.commission; break; } } } // return result; } // // Retrieve Positions ... int GetPositions( XPosition &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // int before = ArraySize(result); // if (forceClean) { Clean(result); } // // Count Positions ... int itemsCount = PositionsTotal(); if (itemsCount <= 0) { return mResult; } // // Loop Through all Positions ... for (int i = itemsCount - 1; i >= 0; i--) { // XPosition iItem; bool isLoaded = iItem.ByIndex(i); if (!isLoaded) { continue; } // // Now we have to Check Given Filters ... bool isFiltersPassed = iItem.IsFiltersPassed( symbol, provider, period, type, mMagicNumber, filterByMagic // ); if (!isFiltersPassed) { continue; } // // Add Filtered Item into Result ... AddRef( iItem, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // void GetPositions( XPosition &longs[], // Hold's Longs Result XPosition &shorts[], // Hold's Shorts Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // // Retrieve Long Positions ... GetPositions( longs, symbol, provider, period, X_POSITION_TYPE_LONG, filterByMagic, forceClean // ); // // Retrieve Short Positions ... GetPositions( shorts, symbol, provider, period, X_POSITION_TYPE_SHORT, filterByMagic, forceClean // ); } // // Select In Profit Positions ... int GetInProfitPositions( XPosition &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // int before = ArraySize(result); // if (forceClean) { Clean(result); } // XPosition positions[]; int positionsCount = GetPositions( positions, symbol, provider, period, type, filterByMagic, forceClean); if (positionsCount <= 0) { return mResult; } // XPosition min; XPosition max; // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.profit <= 0) { continue; } // // Calculate Min and Max ... // // Min ... if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) { min = iPosition; } // // Max ... if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) { max = iPosition; } // bool isSelectionMethodFilterPassed = // (method == NULL || method == X_POSITION_SELECT_ALL) ? true : false; // ; if (!isSelectionMethodFilterPassed) { continue; } // AddRef( iPosition, result // ); } // if (min.IsValid() && (method == X_POSITION_SELECT_MIN || method == X_POSITION_SELECT_BOTH)) { // AddRef( min, result // ); } // if (max.IsValid() && (method == X_POSITION_SELECT_MAX || method == X_POSITION_SELECT_BOTH)) { // AddRef( max, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Select In Drawdown Positions ... int GetInDrawdownPositions( XPosition &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // int before = ArraySize(result); // if (forceClean) { Clean(result); } // XPosition positions[]; int positionsCount = GetPositions( positions, symbol, provider, period, type, filterByMagic, forceClean); if (positionsCount <= 0) { return mResult; } // XPosition min; XPosition max; // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.profit >= 0) { continue; } // // Calculate Min and Max ... // // Min ... if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) { min = iPosition; } // // Max ... if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) { max = iPosition; } // bool isSelectionMethodFilterPassed = // (method == NULL || method == X_POSITION_SELECT_ALL) ? true : false; // ; if (!isSelectionMethodFilterPassed) { continue; } // AddRef( iPosition, result // ); } // if (min.IsValid() && (method == X_POSITION_SELECT_MIN || method == X_POSITION_SELECT_BOTH)) { // AddRef( min, result // ); } // if (max.IsValid() && (method == X_POSITION_SELECT_MAX || method == X_POSITION_SELECT_BOTH)) { // AddRef( max, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Orders ... // // Retrieve Specific Order by Index ... bool GetOrder( int index, // Specified Index XOrder &result // Hold's Result ) { // return result .ByIndex(index); } // // Retrieve Specific Positions Orders ... int GetOrders( ulong ticket, // Positions Ticket XOrder &result[], // Hold's Result bool forceClean = true // Clean Result Array ) { // int mResult = 0; // // Select History by Specified Ticket ... bool isHistorySelected = HistorySelectByPosition(ticket); if (!isHistorySelected) { return mResult; } // int ordersCount = HistoryOrdersTotal(); if (ordersCount <= 0) { return mResult; } // int before = ArraySize(result); // if (forceClean) { Clean(result); } // for (int i = 0; i < ordersCount; i++) { // XOrder iOrder; bool isLoaded = iOrder.HistoryByIndex(i); if (!isLoaded) { continue; } // bool isTicketFilterPassed = // iOrder.ticket = ticket // ; if (!isTicketFilterPassed) { continue; } // AddRef( iOrder, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Retrieve All Orders ... int GetOrders( XOrder &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) ENUM_ORDER_STATE state = NULL, // Order State bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // int before = ArraySize(result); // if (forceClean) { Clean(result); } // // Count Positions ... int itemsCount = OrdersTotal(); if (itemsCount <= 0) { return mResult; } // // Loop Through all Positions ... for (int i = itemsCount - 1; i >= 0; i--) { // XOrder iItem; bool isLoaded = iItem.ByIndex(i); if (!isLoaded) { continue; } // // Now we have to Check Given Filters ... bool isFiltersPassed = iItem.IsFiltersPassed( symbol, provider, period, type, state, mMagicNumber, filterByMagic // ); if (!isFiltersPassed) { continue; } // // Add Filtered Item into Result ... AddRef( iItem, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Retrieve Historical Orders ... int GetOrders( XOrder &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) ENUM_ORDER_STATE state = NULL, // Order State datetime startDate = NULL, // Specify Start Date datetime endDate = NULL, // Specify End Date bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // endDate = NormalizeTime(endDate); // if (!IsValid(startDate)) { startDate = endDate - PeriodSeconds(PERIOD_D1); } // bool isHistorySelected = HistorySelect( startDate, endDate); if (!isHistorySelected) { return mResult; } // int before = ArraySize(result); // if (forceClean) { Clean(result); } // // Count Positions ... int itemsCount = OrdersTotal(); if (itemsCount <= 0) { return mResult; } // // Loop Through all Positions ... for (int i = itemsCount - 1; i >= 0; i--) { // XOrder iItem; bool isLoaded = iItem.HistoryByIndex(i); if (!isLoaded) { continue; } // // Now we have to Check Given Filters ... bool isFiltersPassed = iItem.IsFiltersPassed( symbol, provider, period, type, state, mMagicNumber, filterByMagic // ); if (!isFiltersPassed) { continue; } // // Add Filtered Item into Result ... AddRef( iItem, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Deals ... // // Retrieve Specific Deal by Index ... bool GetDeal( int index, // Specified Index XDeal &result // Hold's Result ) { // return result .ByIndex(index); } // bool GetLastDeal( XDeal &result // Hold's Result ) { // bool mResult = false; // mResult = HistorySelect(0, TimeCurrent()); if (!mResult) { return mResult; } // int lastDealIndex = HistoryDealsTotal() - 1; // mResult = GetDeal( lastDealIndex, result // ); // return mResult; } // // Retrieve Specified Deal's History ... int GetDealsHistory( XDeal &deal, // Specified Deal XOrder &history[], // Deals History bool forceClean = true // Clean Result Array ) { // int result = 0; // if (!deal.IsValid()) { return result; } // result = GetOrders( deal.positionId, history, forceClean); // return result; } // // Retrieve All Deals ... int GetDeals( XDeal &result[], // Hold's Result string symbol = NULL, // Trading Symbol string provider = NULL, // Signal Provider ENUM_TIMEFRAMES period = NULL, // Trading Period ENUM_DEAL_TYPE type = NULL, // Deal Type ENUM_DEAL_ENTRY entry = NULL, // Deal Entry ENUM_DEAL_REASON reason = NULL, // Deal Reason datetime startDate = NULL, // Specify Start Date datetime endDate = NULL, // Specify End Date bool filterByMagic = true, // Get Only Self Open Positions bool forceClean = true // Clean Result Array ) { // int mResult = 0; // endDate = NormalizeTime(endDate); // if (!IsValid(startDate)) { startDate = endDate - PeriodSeconds(PERIOD_D1); } // bool isHistorySelected = HistorySelect( startDate, endDate); if (!isHistorySelected) { return mResult; } // int before = ArraySize(result); // if (forceClean) { Clean(result); } // // Count Positions ... int itemsCount = HistoryDealsTotal(); if (itemsCount <= 0) { return mResult; } // // Loop Through all Positions ... for (int i = itemsCount - 1; i >= 0; i--) { // XDeal iItem; bool isLoaded = iItem.ByIndex(i); if (!isLoaded) { continue; } // // Now we have to Check Given Filters ... bool isFiltersPassed = iItem.IsFiltersPassed( symbol, provider, period, type, entry, reason, mMagicNumber, filterByMagic // ); if (!isFiltersPassed) { continue; } // // Add Filtered Item into Result ... AddRef( iItem, result // ); } // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Support Functions ... // // Check a Position has Support or not ... bool HasSupport( ulong ticket, bool forceOpen = true // ) { // bool result = false; // result = ticket > 0; if (!result) { return result; } // if (forceOpen) { // result = IsOpen(ticket); if (!result) { return result; } } // XPosition positions[]; int positionsCount = GetPositions(positions); result = IsValidSize(positionsCount); if (!result) { return result; } // // Extract Support Positions ... XPosition supports[]; int supportsCount = ExtractSupports( positions, supports // ); result = IsValidSize(supportsCount); if (!result) { return result; } // // Loop Through Supports ... for (int i = 0; i < supportsCount; i++) { // XPosition iSupport = supports[i]; // ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); // result = // (supportedTicket > 0 && ticket == supportedTicket) // || // (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) // ; if (result) { break; } } // return result; } // // Retrieve Specific Position's Supports ... int GetSupports( ulong ticket, XPosition &dest[], // Result ... bool forceOpen = true // ) { // int result = 0; // Clean(dest); // bool hasSupport = HasSupport( ticket, forceOpen // ); if (!hasSupport) { return result; } // XPosition positions[]; int positionsCount = GetPositions(positions); if (!IsValidSize(positionsCount)) { return result; } // // Extract Support Positions ... XPosition supports[]; int supportsCount = ExtractSupports( positions, supports // ); if (!IsValidSize(supportsCount)) { return result; } // // Loop Through Supports ... for (int i = 0; i < supportsCount; i++) { // XPosition iSupport = supports[i]; // ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); // bool isOwn = // (supportedTicket > 0 && ticket == supportedTicket) // || // (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) // ; if (isOwn) { // AddRef( iSupport, dest // ); } } // result = ArraySize(dest); // return result; } // // Retrieve Specific Position's Supports ... int GetSupports( ulong ticket, XOrder &dest[], // Result ... bool forceOpen = true // ) { // int result = 0; // Clean(dest); // bool hasSupport = HasSupport( ticket, forceOpen // ); if (!hasSupport) { return result; } // XOrder orders[]; int ordersCount = GetOrders( orders, NULL, // All Symbols ... NULL, // All Providers ... NULL, // All Periods ... X_POSITION_TYPE_ALL, // All Types ... ORDER_STATE_PLACED, // Untriggere Orders ... true // ); if (!IsValidSize(ordersCount)) { return result; } // // Extract Support Positions ... XOrder supports[]; int supportsCount = ExtractSupports( orders, supports // ); if (!IsValidSize(supportsCount)) { return result; } // // Loop Through Supports ... for (int i = 0; i < supportsCount; i++) { // XOrder iSupport = supports[i]; // ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); // bool isOwn = // (supportedTicket > 0 && ticket == supportedTicket) // || // (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) // ; if (isOwn) { // AddRef( iSupport, dest // ); } } // result = ArraySize(dest); // return result; } // // Tools ... // // Retrieve Last Open Position Ticket ... ulong GetLastOpenPositionTicket() { // ulong result = 0; int positionsCount = PositionsTotal(); if (positionsCount <= 0) { return result; } // result = PositionGetTicket(PositionsTotal() - 1); // return result; } // // Retrieve Last Placed Order Ticket ... ulong GetLastPlacedOrderTicket() { // ulong result = 0; int ordersCount = OrdersTotal(); if (ordersCount <= 0) { return result; } // if (mOrderInfo.SelectByIndex(ordersCount - 1)) { result = mOrderInfo.Ticket(); } // return result; } // // Prepare Dynamic Volume ... double GetDynamicVolume( string _symbol, double _balanceFactor, double _volumeStep // ) { // double result = 0; // // Validate Inputs ... if (!IsValid(_symbol) || _volumeStep <= 0 || _balanceFactor <= 0) { return result; } // // Retrieve Account Balance ... double balance = mAccount.GetBalance(); // double bStep = balance / _balanceFactor; bStep = MathFloor(bStep); if (bStep == 0) { bStep = 1; } // result = bStep * _volumeStep; // result = NormalizeVolume( result, _symbol // ); // return result; } // // Protected ... protected: // // Props ... // // Event Listener Notifiers ... // // State ... void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) { // int count = ArraySize(mTradeStateChangedEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; iHandler(state); } } // // Deals ... void NotifyDealsChangeEvent(int changes) { // int count = ArraySize(mDealsChangedEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnDealsChanged iHandler = mDealsChangedEventHandlers[i]; iHandler(changes); } } // // Orders ... void NotifyOrdersChangeEvent(int changes) { // int count = ArraySize(mOrdersChangedEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; iHandler(changes); } } // // Positions ... void NotifyPositionsChangeEvent(int changes) { // int count = ArraySize(mPositionsChangedEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; iHandler(changes); } } // // StopLoss ... void NotifyStopLossEvent(const XDeal &deal) { // int count = ArraySize(mStopLossEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnStopLoss iHandler = mStopLossEventHandlers[i]; iHandler(deal); } } // // Take Profit ... void NotifyTakeProfitEvent(const XDeal &deal) { // int count = ArraySize(mTakeProfitEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnTakeProfit iHandler = mTakeProfitEventHandlers[i]; iHandler(deal); } } // void NotifyModifyEvent( ulong ticket, double profit, string comment // ) { // int count = ArraySize(mOnModifyEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnModify iHandler = mOnModifyEventHandlers[i]; iHandler( ticket, profit, comment // ); } } // void NotifyForceCloseEvent( ulong ticket, XPosition &position, string comment // ) { // int count = ArraySize(mOnForceCloseEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnForceClose iHandler = mOnForceCloseEventHandlers[i]; iHandler( ticket, position, comment // ); } } // void NotifyPartialCloseEvent( ulong ticket, double profit, string comment // ) { // int count = ArraySize(mOnPartialCloseEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnModify iHandler = mOnPartialCloseEventHandlers[i]; iHandler( ticket, profit, comment // ); } } // void NotifySignalExecuted(XSignal &signal) { // bool has = signal.IsValid() && signal.IsExecuted(); if (!has) { return; } // int count = ArraySize(mOnSignalExecutedEventHandlers); if (count <= 0) { return; } // for (int i = 0; i < count; i++) { // TOnSignal iHandler = mOnSignalExecutedEventHandlers[i]; iHandler(signal); } } // // Tools ... // // Retrieve Specified Position Comment ... string GetPositionComment(ulong ticket) { // string result = NULL; // if (!IsOpen(ticket)) { return result; } // XPosition position; bool isLoaded = position.ByTicket(ticket); if (!isLoaded) { return result; } // result = position.comment; // return result; } // ENUM_TIMEFRAMES GetDealPeriod(XDeal &deal) { // ENUM_TIMEFRAMES result = NULL; // XOrder orders[]; int ordersCount = GetDealsHistory( deal, orders); if (!ordersCount) { return result; } // for (int i = 0; i < ordersCount; i++) { // XOrder iOrder = orders[i]; // if (IsValid(iOrder.comment)) { // ENUM_TIMEFRAMES iPeriod = ExtractPeriod(iOrder.comment); if (IsValid(iPeriod)) { result = iPeriod; break; } } } // return result; } // double GetMaxAllowedEquity() { // double equity = mAccount.GetEquity(); double balance = mAccount.GetBalance(); // double balanceForFactor = MathAbs(equity - balance); if (balanceForFactor <= 0) { balanceForFactor = balance; } else { balanceForFactor = equity; } // double result = balanceForFactor * mMaxAllowedDrawdownFactor; // return result; } // // Private ... private: // // Props ... // int mSlippage; // Slippage ... ulong mMagicNumber; // Magic Number (Unique Identifier) ... // double mMaxAllowedSpread; // Max Allowed Spred for Opening Trades int mMaxAllowedPositions; // Max Allowed Same Positions double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor // XCTradeBase *mTrader; // Base CTrade Manipulated Instance ... // CDealInfo mDealInfo; // Deals Info ... COrderInfo mOrderInfo; // Order Info ... CPositionInfo mPositionInfo; // Positions Info CHistoryOrderInfo mHistoryOrderInfo; // History Orders Info ... // // Position Info Collector ... // // Tools ... // // OnTrade Event Handlers Section ... // // Props ... // int mDaysForRead; // Reading Dates for Trade History Checker ... datetime mEndDate; // End Date for Trade history Checking ... datetime mStartDate; // Start Date for Trade history Checking ... ... int mOrdersCount; // Number of Active orders ... int mPositionsCount; // Number of Open positions ... int mDealsCount; // Number of Deals in the Trade History Checking ... int mHistoryOrdersCount; // Number of Orders in the Trade History Checking ... bool mScanStarted; // a Flag of counter relevance ... // // Event Listeners ... // // Deals Changed Event Handlers ... TOnDealsChanged mDealsChangedEventHandlers[]; // // Orders Changed Event Handlers ... TOnOrdersChanged mOrdersChangedEventHandlers[]; // // Positions Changed Event Handlers ... TOnPositionsChanged mPositionsChangedEventHandlers[]; // // Trade State Changed Event Handlers ... TOnTradeStateChanged mTradeStateChangedEventHandlers[]; // // Signal Executed Event Handlers ... TOnSignal mOnSignalExecutedEventHandlers[]; // TOnModify mOnModifyEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; TOnPartialClose mOnPartialCloseEventHandlers[]; // // TPSL ... TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; // // Reset On Trade Scanner Context ... void ResetOnTradeContext() { // mEndDate = TimeCurrent(); mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); } // // Initial Context Of Trade Scanner ... void InitOnTradeContext() { // ResetLastError(); // mOrdersCount = OrdersTotal(); mPositionsCount = PositionsTotal(); // // load history ... bool selected = HistorySelect(mStartDate, mEndDate); if (!selected) { return; } // // get the current value ... mDealsCount = HistoryDealsTotal(); mHistoryOrdersCount = HistoryOrdersTotal(); // mScanStarted = true; } // // Check Statrt Date In Trade History ... void CheckStartDateInTradeHistory() { // // initial interval, if we were to start working right now .. datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); // // make sure that the start limit of the trade history has not gone // more than 1 day over the intended date ... if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) { // // correct the start date of history to be loaded in the cache ... mStartDate = currStart; // // now reload the trade history for the updated interval ... HistorySelect(mStartDate, mEndDate); // // correct the deal and order counters in history for further comparison mHistoryOrdersCount = HistoryOrdersTotal(); mDealsCount = HistoryDealsTotal(); } } // // Process On Trade Context ... void ProcessOnTradeContext( XOnTradeHandlerState &result // Hold's Result ) { // mEndDate = TimeCurrent(); // ResetLastError(); // // download trading history from the specified interval to the program cache ... bool selected = HistorySelect(mStartDate, mEndDate); if (!selected) { return; } // // get the current values ... int currOrders = OrdersTotal(); int currPositions = PositionsTotal(); int currDeals = HistoryDealsTotal(); int currHistoryOrders = HistoryOrdersTotal(); // // Orders ... // check if the number of active orders has been changed ... if (currOrders != mOrdersCount) { // // number of active orders has been changed ... result.hasNewOrder = true; result.newOrders = currOrders - mOrdersCount; // // update the value ... mOrdersCount = currOrders; } // // Positions ... // changes in the number of open positions ... if (currPositions != mPositionsCount) { // // number of open positions has been changed ... result.hasNewPosition = true; result.newPositions = currPositions - mPositionsCount; // // update the value ... mPositionsCount = currPositions; } // // Deals ... // changes in the number of deals in the trade history cache ... if (currDeals != mDealsCount) { // // number of deals in the trade history cache has been changed ... result.hasNewDeal = true; result.newDeals = currDeals - mDealsCount; // // update the value ... mDealsCount = currDeals; } // // History Orders ... // changes in the number of history orders in the trade history cache ... if (currHistoryOrders != mHistoryOrdersCount) { // // number of history orders in the trade history cache has been changed ... result.hasNewHistoryOrder = true; result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; // // update the value ... mHistoryOrdersCount = currHistoryOrders; } // // checking if it is necessary to change the limits of the trade history to be requested in cache ... CheckStartDateInTradeHistory(); } }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Classes\x-saherelm.x-volume.class.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCVolume // Description: provides all Requirements for Volume Managing ... // // // 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 // // Template Variables of Inputs for Using ... // input group "Volume"; // input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_STATIC; // Volume Applying Type // input double eaStaticVoluem = X_MIN_VOLUME; // Static Volume // input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume // input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing // input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade // input double eaConstantPercent = 0.0; // Constant Percent of Balance Per Trade // input double eaConstantBalance = 0.0; // Constant Balance for Calculations // XCVolume *eaVolume; // eaVolume = new XCVolume(); // bool result = eaVolume.Init( // eaVolumeSelect, // eaStaticVoluem, // eaDynamicVolumeStepBalance, // eaDynamicVolumeStepVolume, // eaConstantRiskBalance, // eaConstantPercent, // eaConstantBalance // // ); // if (!result) { // return INIT_FAILED; // } // // Imports ... #include "../Classes/x-saherelm.x-account.class.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5" // // Definitions ... #define X_MIN_VOLUME 0.01 // enum ENUM_X_VOLUME_SELECT_TYPE { X_VOLUME_NONE, // None X_VOLUME_STATIC, // Static Volume X_VOLUME_CURRENT, // Current Balance X_VOLUME_EQUITY, // Current Equity X_VOLUME_CONSTANT // Constant Value }; // bool IsValid(ENUM_X_VOLUME_SELECT_TYPE value) { // bool result = false; // result = value != X_VOLUME_NONE; // return result; } // string ToString(ENUM_X_VOLUME_SELECT_TYPE value) { // string result = NULL; // result = EnumToString(value); // return result; } // // Implementation ... class XCVolume : public XCBase { // // Public ... public: // // Props ... XCAccount *account; // // Constructor ... XCVolume() { // account = new XCAccount(); // Default(); } // // Deconstructor ... ~XCVolume() { // ZeroMemory(account); } // bool Init( ENUM_X_VOLUME_SELECT_TYPE _SelectType, double _StaticVolume, double _DynamicVolumeStepBalance, double _DynamicVolumeStepVolume, double _ConstantRiskBalance, double _ConstantPercent, double _ConstantBalance // ) { // bool result = false; // mVolumeType = _SelectType; mStaticVolume = _StaticVolume; mConstantPercent = _ConstantPercent; mConstantBalance = _ConstantBalance; mConstantRiskBalance = _ConstantRiskBalance; mDynamicVolumeStepVolume = _DynamicVolumeStepVolume; mDynamicVolumeStepBalance = _DynamicVolumeStepBalance; // result = // CanUseStaticVolume() || CanUseDynamicVolume() || CanUseConstantRiskBalance() || CanUseConstantBalancePercent() // ; // return result; } // // Prperties ... /** * Get Volume Calculating Method ... * * @return (ENUM_X_VOLUME_SELECT_TYPE) */ ENUM_X_VOLUME_SELECT_TYPE VolumeType() { return mVolumeType; } /** * Set Volume Calculating Method ... * * @param value: ENUM_X_VOLUME_SELECT_TYPE member ... */ void VolumeType(ENUM_X_VOLUME_SELECT_TYPE value) { mVolumeType = value; } /** * Get Static Volume ... * * @return ( double ) */ double StaticVolume() { return mStaticVolume; } /** * Set Static Volume ... * * @param value: double */ void StaticVolume(double value) { // value = NormalizeDouble(value, 0.01, 1); // mStaticVolume = value; } /** * Get Dynamic Volume Step Balance ... * used to Calculate Final Lottage ... * * @return ( double ) */ double DynamicVolumeStepBalance() { return mDynamicVolumeStepBalance; } /** * Set Dynamic Volume Step Balance ... * used to Calculate Final Lottage ... * * @param value: Argument 1 */ void DynamicVolumeStepBalance(double value) { // value = NormalizeDouble(value, 0); // mDynamicVolumeStepBalance = value; } /** * Get Dynamic Volume Step Volume ... * used to Calculate Final Lottage ... * how much increase Final Volume based oBalance Step ... * * @return ( double ) */ double DynamicVolumeStepVolume() { return mDynamicVolumeStepVolume; } /** * Get Dynamic Volume Step Volume ... * used to Calculate Final Lottage ... * how much increase Final Volume based oBalance Step ... * * @param value: double */ void DynamicVolumeStepVolume(double value) { // value = NormalizeDouble(value, 0.01, 0.1); // mDynamicVolumeStepVolume = value; } /** * Get Constant Balance Use for Dyamic Volume Calculation ... * * @return ( double ) */ double ConstantBalance() { return mConstantBalance; } /** * Set Constant Balance Use for Dyamic Volume Calculation ... * * @param value: Argument 1 */ void ConstantBalance(double value) { // value = NormalizeDouble(value, 0); // mConstantBalance = value; } /** * Get Constant Risk Value Based on Account Currency ... * * @return ( double ) */ double ConstantRiskBalance() { return mConstantRiskBalance; } /** * Get Constant Risk Value Based on Account Currency ... * * @param value: double */ void ConstantRiskBalance(double value) { // value = NormalizeDouble(value, 0); // mConstantRiskBalance = value; } /** * Get Constant Percent Based On Selected Balance ... * * @return ( double ) */ double ConstantPercent() { return mConstantPercent; } /** * Set Constant Percent Based On Selected Balance ... * * @param value: double ... */ void ConstantPercent(double value) { // value = NormalizeDouble(value, 0, 100); // mConstantPercent = value; } // // Tools ... /** * Retrieve Balance based on Provided Volume Type ... * * @return ( double ) */ double GetBalance() { // double result = 0; // if (!IsValid(mVolumeType)) { return result; } // if (mConstantBalance > 0 && mVolumeType == X_VOLUME_CONSTANT) { result = mConstantBalance; } else if (mVolumeType == X_VOLUME_CURRENT) { result = account.GetBalance(); } else if (mVolumeType == X_VOLUME_EQUITY) { result = account.GetEquity(); } // return result; } /** * Retrieve Balance based on Provided Volume Type ... * * @return ( double ) */ double GetBalance(ENUM_X_VOLUME_SELECT_TYPE type) { // double result = 0; // if (!IsValid(type)) { return result; } // if (mConstantBalance > 0 && type == X_VOLUME_CONSTANT) { result = mConstantBalance; } else if (type == X_VOLUME_CURRENT) { result = account.GetBalance(); } else if (type == X_VOLUME_EQUITY) { result = account.GetEquity(); } // return result; } /** * Calculate Volume Based On Given Configuration ... * * @param symbol: string, Trading Symbol ... * @param entry: double, Entry Price ... * @param sl: double, Stop Loss Price ... * * @return ( double ) */ double CalculateVolume( string symbol, double entry, double sl // ) { // double result = X_MIN_VOLUME; // bool has = false; // // Validate Args ... has = sl > 0 && entry > 0 && IsValid(symbol); if (!has) { return result; } // // Retrieve Balance Type ... double balance = GetBalance(); double points = GetPoints(symbol); double riskPrice = MathAbs(entry - sl); double riskInPoints = riskPrice / points; // has = CanUseStaticVolume(); if (has) { result = mStaticVolume; } // has = CanUseDynamicVolume(); if (has) { // double multiplier = balance / mDynamicVolumeStepBalance; if (multiplier < 0) { multiplier = 1; } // result = multiplier * mDynamicVolumeStepVolume; } // has = CanUseConstantRiskBalance(); if (has) { // result = account.CalculateVolume( symbol, mConstantRiskBalance, riskInPoints // ); } // has = CanUseConstantBalancePercent(); if (has) { // double riskAmountPerBalance = (mConstantPercent * balance) / 100; // result = account.CalculateVolume( symbol, riskAmountPerBalance, riskInPoints // ); } // if (result < X_MIN_VOLUME) { result = X_MIN_VOLUME; } // // Normalize Volume ... result = NormalizeVolume(result, symbol); // return result; } /** * Calculate Volume Based On Given Configuration ... * * @param signal: XSignal instance reference, provided required Data ... * * @return ( double ) */ double CalculateVolume(XSignal &signal) { // double result = X_MIN_VOLUME; // if (!signal.IsValid()) { return result; } // result = CalculateVolume( signal.symbol, signal.entry, signal.sl // ); // return result; } /** * Calculate Specified Percent of Selected Balance for Volume ... * * @param percent: double, percent of Balance Risking ... * @param symbol: string, Trading Symbol ... * @param entry: double, Entry Price ... * @param sl: double Stop Loss Price ... * * @return ( double ) */ double CalculateVolume( ENUM_X_VOLUME_SELECT_TYPE selectType, double percent, string symbol, double entry, double sl // ) { // double result = X_MIN_VOLUME; // bool has = false; // // Validate Args ... has = sl > 0 && entry > 0 && percent > 0 && IsValid(symbol) && IsValid(selectType) && (selectType == X_VOLUME_EQUITY || selectType == X_VOLUME_CURRENT); if (!has) { return result; } // // Retrieve Balance Type ... double points = GetPoints(symbol); double riskPrice = MathAbs(entry - sl); double balance = GetBalance(selectType); double riskInPoints = riskPrice / points; // double riskAmountPerBalance = (percent * balance) / 100; // result = account.CalculateVolume( symbol, riskAmountPerBalance, riskInPoints // ); // return result; } // // Protected ... protected: // // Tools ... /** * Set Default Props ... */ void Default() { // VolumeType(X_VOLUME_STATIC); StaticVolume(0.01); // ConstantBalance(0); ConstantPercent(0); ConstantRiskBalance(0); // DynamicVolumeStepBalance(0); DynamicVolumeStepVolume(0.01); } /** * Check Configuration is Valid For Static Volume ... * * @return ( bool ) */ bool CanUseStaticVolume() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // // Static Volume ... result = // mVolumeType == X_VOLUME_STATIC && mStaticVolume > 0 && // mDynamicVolumeStepBalance == 0 && // mConstantBalance == 0 && mConstantPercent == 0 && mConstantRiskBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Dynamic Volume ... * * @return ( bool ) */ bool CanUseDynamicVolume() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mDynamicVolumeStepBalance > 0 && mDynamicVolumeStepVolume > 0 && // mStaticVolume == 0 && mConstantPercent == 0 && mConstantRiskBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Constant Risk Balance ... * * @return ( bool ) */ bool CanUseConstantRiskBalance() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mConstantRiskBalance > 0 && // mStaticVolume == 0 && mConstantPercent == 0 && mDynamicVolumeStepBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Constant Risk Percent ... * * @return ( bool ) */ bool CanUseConstantBalancePercent() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mConstantPercent > 0 && // mStaticVolume == 0 && mConstantRiskBalance == 0 && mDynamicVolumeStepBalance == 0 // ; // return result; } // // Private ... private: // // Props ... // ENUM_X_VOLUME_SELECT_TYPE mVolumeType; // Balance Type ... // // Static Volume ... double mStaticVolume; // Static Volume ... // double mDynamicVolumeStepBalance; // Step of Balance ... double mDynamicVolumeStepVolume; // Step of Volume ... // double mConstantBalance; // Constant Balance .... double mConstantRiskBalance; // Constant Risk Balance ... double mConstantPercent; // Constant Percent of Balance ... }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Documents\Helpers\x-saherelm.x121.xcc.helper.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Helper Class Library // ---------------------------------------------- // Name: XSCX121XCCHelper // Description: provides all Indicator // Helper requirements ... // // // 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.x-helper.class.mq5" // // Definitions ... // // Input Models ... struct X121XCCInputs { // // Props ... // // Chart Style ... ENUM_CHART_MODE mode; // Mode color upColor; // Up Color color downColor; // Down Color color lineColor; // Line mode and Doji candlestick Color color bearishColor; // Bullish Color color bullishColor; // Bearish Color color volumesColor; // Volumes Color // // Presentation ... bool showCandles; // Show Candles // // Constructor(s) ... X121XCCInputs() { // Clean(); } // // Tools ... // // Clean ... void Clean() { // mode = CHART_CANDLES; // upColor = CLR_NONE; downColor = CLR_NONE; lineColor = CLR_NONE; bearishColor = CLR_NONE; bullishColor = CLR_NONE; volumesColor = CLR_NONE; // showCandles = false; // ZeroMemory(this); } // // Default ... void Default() { // mode = CHART_CANDLES; // upColor = clrLime; downColor = clrRed; lineColor = clrLime; bearishColor = clrRed; bullishColor = clrLime; volumesColor = clrGreen; // showCandles = true; } // // Hide all Visible Buffers ... void Hide() { showCandles = false; } // // Validate ... bool IsValid() { // bool result = false; // result = // true // ; // return result; } // // Retrieve MAx Length ... int Max() { // int result = 0; // result = MathMax(0, 0); // return result; } }; // // Class ... class XCX121XCCHelper : public XCBaseHelper { // // Public ... public: // // Props ... // // Constructors ... XCX121XCCHelper() : XCBaseHelper(_Symbol, _Period) { } // // Deconstructor ... ~XCX121XCCHelper() { mInputs.Clean(); } // // Tools ... bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period X121XCCInputs &inputs // Inputs ) { // bool result = false; // mSymbol = symbol; mPeriod = period; // result = inputs.IsValid(); if (!result) { return result; } // mInputs = inputs; // mHandler = iCustom( mSymbol, mPeriod, "x-saherelm.x121.xcc", // // Inputs ... // // Chart Style ... "", mInputs.mode, // Mode mInputs.upColor, // Up Color mInputs.downColor, // Down Color mInputs.lineColor, // Line mode and Doji candlestick Color mInputs.bullishColor, // Bearish Color mInputs.bearishColor, // Bullish Color mInputs.volumesColor, // Volumes Color // // Presentation ... "", mInputs.showCandles // Show Candles // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Inputs ... // X121XCCInputs GetInputs() { return mInputs; } // bool SetInputs( X121XCCInputs &inputs // Configs ) { // return Init( mSymbol, mPeriod, inputs // ); } // // Protected ... protected: // // Private ... private: // // Props ... X121XCCInputs mInputs; // Inputs ... }; // // Tools ... ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Documents\Helpers\x-saherelm.x121.xct.helper.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Helper Class Library // ---------------------------------------------- // Name: XSCX121XCTHelper // Description: provides all Indicator // Helper requirements ... // // // 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.x-helper.class.mq5" // // Definitions ... // // Input Models ... struct X121XCTInputs { // // Props ... // string font; // Font int fontSize; // Font Size; color clr; // Text Color ENUM_BASE_CORNER corner; // Text Position // // Presentation ... bool showCandleTime; // Show Candle Time // // Constructor(s) ... X121XCTInputs() { Clean(); } // // Tools ... // // Clean ... void Clean() { // font = NULL; fontSize = 15; clr = CLR_NONE; corner = CORNER_RIGHT_LOWER; // // Presentation ... showCandleTime = false; // ZeroMemory(this); } // // Default ... void Default() { // font = "Arial"; fontSize = 15; clr = clrYellow; corner = CORNER_RIGHT_LOWER; // // Presentation ... showCandleTime = true; } // // Hide all Visible Buffers ... void Hide() { showCandleTime = false; } // // Validate ... bool IsValid() { // bool result = false; // result = // true // ; // return result; } // // Retrieve MAx Length ... int Max() { // int result = 0; // result = MathMax(0, 0); // return result; } }; // // Class ... class XCX121XCTHelper : public XCBaseHelper { // // Public ... public: // // Props ... // // Constructors ... XCX121XCTHelper() : XCBaseHelper(_Symbol, _Period) { } // // Deconstructor ... ~XCX121XCTHelper() { mInputs.Clean(); } // // Tools ... bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period X121XCTInputs &inputs // Inputs ) { // bool result = false; // mSymbol = symbol; mPeriod = period; // result = inputs.IsValid(); if (!result) { return result; } // mInputs = inputs; // mHandler = iCustom( mSymbol, mPeriod, "x-saherelm.x121.xct", // // Inputs ... mInputs.fontSize, // Font Size ... mInputs.font, // Font ... mInputs.clr, // Text Color ... mInputs.corner, // Text Position ... // // Presentation ... "", mInputs.showCandleTime // Show Candle Time // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Inputs ... // X121XCTInputs GetInputs() { return mInputs; } // bool SetInputs( X121XCTInputs &inputs // Configs ) { // return Init( mSymbol, mPeriod, inputs // ); } // // Protected ... protected: // // Private ... private: // // Props ... X121XCTInputs mInputs; // Inputs ... }; // // Tools ... ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Documents\Indicators\x-saherelm.x121.xcc.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Candle Styles // --------------------------------------------------- // Name: X121 XCC // Description: Candle Styles ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121 XCC Indicator" #property strict // // START Constants ... // // // Indicator Short Name ... #define ShortName "X121 XCC" // // Holds an SnapShot of Charts Configuration ... struct XChartStyle { // // chart's ID ... long chartId; // // chart's mode ... ENUM_CHART_MODE mode; // // show bid line ... bool showBidLine; // // show ask line ... bool showAskLine; // // show grids on chart ... bool showGrid; // // show volumes ... bool showVolumes; // // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... bool showTradeLevels; // // chart autoscroll ... bool autoScroll; // // chart quick navigation state ... bool quickNavigation; // // chart's foreground color ... color foreGroundColor; // // chart's background color ... color backGroundColor; // // Up Color ... color upColor; // // Down Color ... color downColor; // // Bullish color ... color bullishColor; // // Bearish color ... color bearishColor; // // grid color ... color gridColor; // // bid line color ... color bidLineColor; // // ask line color ... color askLineColor; // // line mode and doji candlestick color ... color lineColor; // // Color of stop order levels (Stop Loss and Take Profit) ... color stopColor; // // volumes color ... color volumesColor; }; // // END Constants ... // // // START Inputs ... // // input group "Chart Style"; input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode input color upColor = clrGreen; // Up Color input color downColor = clrRed; // Down Color input color lineColor = clrGreen; // Line mode and Doji candlestick Color input color bullishColor = clrGreen; // Bullish Color input color bearishColor = clrRed; // Bearish Color input color volumesColor = clrGreen; // Volumes Color // input group "Presentation"; input bool showCandles = true; // Show Candles // // END Inputs ... // // // START Includes and Imports ... // // // Includes Draw Library ... #include "../Libraries/x-saherelm.draw.lib.mq5" // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // END Includes and Imports ... // // // START Buffers ... // // #property indicator_chart_window // #property indicator_buffers 0 #property indicator_plots 0 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // // int maxLength; // XChartStyle chartStyle; XChartStyle clearStyle; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // drawPrefix = ShortName; // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... maxLength = ExtractMaxLengthOfInputs(); // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Apply Chart Style ... ApplyCustomChartStyle(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // // Prepare Buffers ... ArraySetAsSeries(time, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(spread, true); // // this counts Available Bars ... int limit; // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { CalculateBuffers(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = true; // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // return result; } // // Define Indexes and Styles ... void DefineBuffers() { } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // // Calculate Buffers ... void CalculateBuffers( int bar_index // Selected Bar Index ) { } // // Apply Custom Chart Style ... void ApplyCustomChartStyle() { // // Read Current Chart Config and Store it ... ReadChartStyle(); // // After Reading Current Chart Style ... // we have to Save Configs and Change Styles ... clearStyle = chartStyle; // clearStyle.upColor = CLR_NONE; clearStyle.downColor = CLR_NONE; clearStyle.lineColor = CLR_NONE; clearStyle.bullishColor = CLR_NONE; clearStyle.bearishColor = CLR_NONE; // // Decide to Show or not Candles based on User Input ... if (showCandles) { SetChartStyle(chartStyle); } else { SetChartStyle(clearStyle); } } // // Read Previous Chart Style ... void ReadChartStyle() { // // Retrieve Current Chart ID ... long chartId = ChartID(); chartStyle.chartId = chartId; // // Retrieve Chart Mode ... chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); // chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); // chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); // chartStyle.mode = mode; chartStyle.upColor = upColor; chartStyle.downColor = downColor; chartStyle.lineColor = lineColor; chartStyle.bearishColor = bearishColor; chartStyle.bullishColor = bullishColor; chartStyle.volumesColor = volumesColor; } // // Set Chart Style ... void SetChartStyle( XChartStyle &mChartStyle // Chart Style to Apply ) { // ApplyChartStyle( mChartStyle.chartId, mChartStyle.mode, mChartStyle.showBidLine, mChartStyle.showAskLine, mChartStyle.showGrid, mChartStyle.showVolumes, mChartStyle.showTradeLevels, mChartStyle.autoScroll, mChartStyle.quickNavigation, mChartStyle.foreGroundColor, mChartStyle.backGroundColor, mChartStyle.upColor, mChartStyle.downColor, mChartStyle.bullishColor, mChartStyle.bearishColor, mChartStyle.gridColor, mChartStyle.bidLineColor, mChartStyle.askLineColor, mChartStyle.lineColor, mChartStyle.stopColor, mChartStyle.volumesColor); } // // END Functions ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Documents\Indicators\x-saherelm.x121.xct.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // --------------------------------------------- // Name: X121 XCT // Description: Trend Magic Indicator ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121 XCT Indicator" #property strict // // START Constants ... // // #define ShortName "X121 XCT" #include "../Libraries/x-saherelm.common.lib.mq5" // // END Constants ... // // // START Inputs ... // // input int fontSize = 15; // Font Size input string font = "Arial"; // Font input color clr = clrYellow; // Text Color input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position // input group "Presentation"; input bool showTimer = true; // Show Candle Time // // END Inputs ... // // // START Buffers ... // // #property indicator_chart_window // #property indicator_buffers 0 #property indicator_plots 0 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // bool isCreatedObject; string tag; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... // tag = ShortName + _Symbol + ToString(_Period); // // Set Indicator ShortName ... SetIndicatorName(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // Delete Object ... ObjectDelete(0, tag); // Comment(""); } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // if (!showTimer) { return rates_total; } // XBarRemainsTime barRemains; barRemains.Init( _Symbol, _Period // ); // string msg = barRemains .ToString( "", "", "", "", "", ":", true // ); // long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); // string _sp = ""; if (mSpread < 10) _sp = ".."; else if (mSpread < 100) _sp = "."; // string objText = "Spread: " + IntegerToString(mSpread) + _sp + ", Next Bar in: " + msg; // if (IsValid(tag) && !isCreatedObject) { CreateIndicatorObject(); } // if (isCreatedObject) { ObjectSetString(0, tag, OBJPROP_TEXT, objText); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // void CreateIndicatorObject() { // if (!showTimer || !IsValid(tag)) { return; } // isCreatedObject = ObjectCreate(0, tag, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, tag, OBJPROP_CORNER, corner); ObjectSetInteger(0, tag, OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, tag, OBJPROP_YDISTANCE, 2); // ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; switch (corner) { case CORNER_LEFT_UPPER: Anchor = ANCHOR_LEFT_UPPER; break; case CORNER_RIGHT_UPPER: Anchor = ANCHOR_RIGHT_UPPER; break; case CORNER_LEFT_LOWER: Anchor = ANCHOR_LEFT_LOWER; break; case CORNER_RIGHT_LOWER: Anchor = ANCHOR_RIGHT_LOWER; break; } // int mFontSize = fontSize > 0 ? fontSize : 10; // string mFont = IsValid(font) ? font : "Arial"; // ObjectSetString(0, tag, OBJPROP_FONT, mFont); ObjectSetInteger(0, tag, OBJPROP_COLOR, clr); ObjectSetInteger(0, tag, OBJPROP_ANCHOR, Anchor); ObjectSetInteger(0, tag, OBJPROP_FONTSIZE, mFontSize); } // // END Functions ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Experts\x-saherelm.backtester.ea.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center XTest MQL5 Expert Advisor // ------------------------------------------------- // Name: XBackTester // Description: a Backtest Tools Strategy Tester // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // //////////////////////////////////////////////////////x // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property icon "../Images/SaherElm_Logo_Color.ico" #property description "SaherElm XBackTester" #property strict // #define ShortName "XBackTester" // // Imports ... #include "../Classes/x-saherelm.x-backtester.expert.class.mq5" // // Definitions ... // // Inputs ... // // Common ... input group "Common"; input long eaMagicNumber = 78692110; // Magic Number input int eaSlippage = 10; // Slippgae input string eaLogSuffix = ""; // Log Suffix // // Alert ... // Here we Provider All Requirements for // Configuring Alert Provider ... input group "Alert"; input bool eaEnableAlerts = true; // Enable Alerts input bool eaLogAlerts = true; // Log Alerts input bool eaMailAlerts = false; // Mail Alerts input bool eaPushAlerts = false; // Push Alerts input bool eaTerminalAlerts = false; // Terminal Alerts // // Define Local Variables ... // string eaLogTag; // EA Log Prefix ... XCBackTesterEA *eaExpert; // EA Expert ... // // Event Handlers ... // // Initialization ... int OnInit() { // // Preparing Tags ... string eaTag = (IsValid(eaLogSuffix) ? eaLogSuffix + "_" : "") + ShortName; // // Validate Inputs and Required Parameters // for EA to Works fine ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Timer ... if (!InitTimer()) { return INIT_FAILED; } // // Configure EA Expert Class ... eaExpert = new XCBackTesterEA(); // // Symbol / Period ... eaExpert.symbol = _Symbol; eaExpert.period = _Period; // // Common ... eaExpert.eaMagicNumber = eaMagicNumber; eaExpert.eaSlippage = eaSlippage; eaExpert.eaLogSuffix = eaTag; // // Alert ... eaExpert.eaEnableAlerts = eaEnableAlerts; eaExpert.eaLogAlerts = eaLogAlerts; eaExpert.eaMailAlerts = eaMailAlerts; eaExpert.eaPushAlerts = eaPushAlerts; eaExpert.eaTerminalAlerts = eaTerminalAlerts; // // Attach Event Handlers ... eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); eaExpert.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); eaExpert.AddOnModifyPositionEventHandler(OnPositionModified); eaExpert.AddOnPositionsChangedEventHandler(OnPositionsChanged); eaExpert.AddOnTradeStateChangedEventHandler(OnTradeStateChanged); eaExpert.AddOnForceClosePositionEventHandler(OnPositionForceClosed); eaExpert.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed); // // Configure Other Requirements ... // eaExpert.volume = 0; // eaExpert.riskInPoint = 0; // eaExpert.allowedTPSLStep = 0; // eaExpert.riskToRewardRatio = 0; // eaExpert.minAllowedRiskInPoint = 0; // // Try to Initialize eaExpert ... bool isInited = eaExpert.HandleOnInit(); if (!isInited) { // Print(ShortName, ": Initialization Failed ..."); return INIT_FAILED; } // Print(ShortName, ": Initialized Successfully ..."); return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // Destroy Timer ... eaExpert.HandleOnDeInit(); // delete eaExpert; ZeroMemory(eaExpert); } // // On Tick Handler ... void OnTick() { eaExpert.HandleOnTick(); } // // Handle On Trade Event ... void OnTrade() { eaExpert.HandleOnTrade(); } // // On Timer ... void OnTimer() { eaExpert.HandleOnTimer(); } // // Chart Event Handler ... void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam); } // // Custom Functions ... /** * Validate all Inputs of Expert Adviser ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // string errMessage = ""; // bool isCommonValid = ( // eaSlippage > 0 && eaMagicNumber > 0 // ); if (!isCommonValid) { // errMessage += "common configurations error;" + "\n"; } // result = // // Common ... isCommonValid && // // Otere ... true // ; // if (!result) { // // Since here Logger not Initiallized, we Use Raw Print Command ... Print(ShortName + " Errors: \n", errMessage); } // return result; } /** * Initialize Timer ... * * @return ( bool ) */ bool InitTimer() { // bool result = false; // // TODO: Initialize Timer if necessary ... // result = EventSetTimer(1); // result = EventSetMillisecondTimer(100); result = true; // return result; } /** * Destroy Timer ... */ void DestroyTimer() { // // TODO: Use This ... // EventKillTimer(); } // // Trade Event Handlers ... /** * Handle StopLoss Triggered Positions ... * * @param deal: XDeal instance ... */ void OnStopLossTriggered(const XDeal &deal) { eaExpert.HandleOnStopLossTriggered(deal); } /** * Handle Take Profit Triggered Positions ... * * @param deal: XDeal instance ... */ void OnTakeProfitTriggered(const XDeal &deal) { eaExpert.HandleOnTakeProfitTriggered(deal); } /** * Handle Force Close a Position ... * * @param ticket: ULONG ... * @param position: XPosition instance ... * @param comment: String ... */ void OnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // eaExpert.HandleOnPositionForceClosed( ticket, position, comment // ); } /** * Handle Deals Changes ... * * @param count: Integer, Number of Changes ... */ void OnDealsChanged(int count) { eaExpert.HandleOnDealsChanged(count); } /** * Handle Orders Changes ... * * @param count: Integer, Number of Changes ... */ void OnOrdersChanged(int count) { eaExpert.HandleOnOrdersChanged(count); } /** * Handle Positions Changes ... * * @param count: Integer, Number of Changes ... */ void OnPositionsChanged(int count) { eaExpert.HandleOnPositionsChanged(count); } /** * Handle Position Modified ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionModified( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionModified( ticket, profit, comment // ); } /** * Handle Position Partial Closed ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionPartialClosed( ticket, profit, comment // ); } /** * Handle Trade State Changed ... * * @param state: XOnTradeHandlerState instance ... */ void OnTradeStateChanged(const XOnTradeHandlerState &state) { eaExpert.HandleOnTradeStateChanged(state); } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Experts\x-saherelm.x-expert.ea.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Expert Advisor // ------------------------------------------------- // Name: XBaseEA // Description: Base Expert Advisor as Template ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property icon "../Images/SaherElm_Logo_Color.ico" #property description "SaherElm Based Expert Advisor" #property strict // #define ShortName "XBaseEA" // // Importts ... #include "../Classes/x-saherelm.x-expert.class.mq5" // // Inputs ... // // Common ... input group "Common"; input long eaMagicNumber = 1694056; // Magic Number input int eaSlippage = 10; // Slippgae input string eaLogSuffix = ""; // Log Suffix // // Symbols // [ // Name| // Symbol| // period| // (ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)| // maxAllowedSpread| // maxAllowedPosition| // ( // restrictionsPeriod, // restrictionsMultiplier, // maxAllowedTPs, // maxAllowedSLs, // maxAllowedTrades, // closeAllOpenTradesAt // ) // ] // // // [XNAME|XAUUSDb|M5|(ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)|25.0|5|(XTRADE_RESTRICATION_DAILY,1,0,2,0)] input string eaSymbolConfiguration = "[XNAME|XAUUSDb|M5|(ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)|25.0|5|(XTRADE_RESTRICATION_DAILY,3,0,2,0)]"; // Symbol Configurations // // Management ... input group "Management"; input bool eaAllowGuards = false; // Allow Guards input bool eaAllowTrade = true; // Allow Trade on Signals input bool eaAllowLongs = true; // Allow Long Trades input bool eaAllowShorts = true; // Allow Short Trades input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade // // Volume ... input group "Volume"; input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_CONSTANT; // Volume Applying Type input double eaStaticVoluem = 0.0; // Static Volume input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade input double eaConstantPercent = 1; // Constant Percent of Balance Per Trade input double eaConstantBalance = 1000.0; // Constant Balance for Calculations // // Alert ... input group "Alert"; input bool eaEnableAlerts = true; // Enable Alerts input bool eaSaveAlerts = true; // Save Alerts input bool eaLogAlerts = true; // Log Alerts input bool eaMailAlerts = false; // Mail Alerts input bool eaPushAlerts = true; // Push Alerts input bool eaTerminalAlerts = false; // Terminal Alerts // // Reports ... input group "Reports"; input bool eaReportNewMonths = false; // Report New Month input bool eaReportNewWeeks = false; // Report New Weeks input bool eaReportNewDays = true; // Report New Days input bool eaReportNewHours = false; // Report New Hours input bool eaReportTrades = true; // Report Trades input bool eaReportSignals = true; // Report Signals input bool eaReportRestrictions = true; // Report Restrictions input bool eaReportProtector = true; // Report Protector Actions input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished // // Collector ... input group "Collector"; input bool eaSaveTrades = true; // Save Trades input bool eaSaveSignals = true; // Save Signals input bool eaSaveWins = true; // Save Winning Conditions input bool eaSaveLosts = true; // Save Lost Conditions input bool eaSaveRestrictions = true; // Save Restriction Reports // // Management Panel ... input group "Management Panel"; input bool eaShowPanel = false; // Show Management Panel double eaPanelAllowedTPSLStep = 10; // Value for Change TP/SL in Each Step double eaPanelMinAllowedRiskInPoint = 20; // Min Allowed Risk in Point double eaPanelRiskInPoint = 50; // Risk in Point per Trades double eaPanelRiskToRewardRatio = 2.0; // Risk To Reward per Trades double eaPanelVolume = X_MIN_VOLUME; // Default volume Per Trade // // Variables ... // XCBaseExpert *eaExpert; // // Event Handlers ... /** * Initialize EA Process ... * * @return ( int ) */ int OnInit() { // // Preparing Tags ... string eaTag = (IsValid(eaLogSuffix) ? eaLogSuffix + "_" : "") + ShortName; // // Validate Inputs and Required Parameters ... // for EA to Works fine ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Timer ... if (!InitTimer()) { return INIT_FAILED; } // // Configure EA Expert Class ... eaExpert = new XCBaseExpert(); // // Setting All Inputs to Expert Adviser Class ... // // Common ... eaExpert.eaMagicNumber = eaMagicNumber; eaExpert.eaSlippage = eaSlippage; eaExpert.eaLogSuffix = eaTag; // // Symbols ... eaExpert.eaSymbolConfiguration = eaSymbolConfiguration; // // Management ... eaExpert.eaAllowGuards = eaAllowGuards; eaExpert.eaAllowTrade = eaAllowTrade; eaExpert.eaAllowLongs = eaAllowLongs; eaExpert.eaAllowShorts = eaAllowShorts; eaExpert.eaMaxAllowedDrawdownFactor = eaMaxAllowedDrawdownFactor; // // Volume ... eaExpert.eaVolumeSelect = eaVolumeSelect; eaExpert.eaStaticVoluem = eaStaticVoluem; eaExpert.eaDynamicVolumeStepBalance = eaDynamicVolumeStepBalance; eaExpert.eaDynamicVolumeStepVolume = eaDynamicVolumeStepVolume; eaExpert.eaConstantRiskBalance = eaConstantRiskBalance; eaExpert.eaConstantPercent = eaConstantPercent; eaExpert.eaConstantBalance = eaConstantBalance; // // Alert ... eaExpert.eaEnableAlerts = eaEnableAlerts; eaExpert.eaSaveAlerts = eaSaveAlerts; eaExpert.eaLogAlerts = eaLogAlerts; eaExpert.eaMailAlerts = eaMailAlerts; eaExpert.eaPushAlerts = eaPushAlerts; eaExpert.eaTerminalAlerts = eaTerminalAlerts; // // Reports ... eaExpert.eaReportNewMonths = eaReportNewMonths; eaExpert.eaReportNewWeeks = eaReportNewWeeks; eaExpert.eaReportNewDays = eaReportNewDays; eaExpert.eaReportNewHours = eaReportNewHours; eaExpert.eaReportTrades = eaReportTrades; eaExpert.eaReportSignals = eaReportSignals; eaExpert.eaReportRestrictions = eaReportRestrictions; eaExpert.eaReportProtector = eaReportProtector; eaExpert.eaReportAfterTradesBalance = eaReportAfterTradesBalance; // // Collector ... eaExpert.eaSaveTrades = eaSaveTrades; eaExpert.eaSaveSignals = eaSaveSignals; eaExpert.eaSaveWins = eaSaveWins; eaExpert.eaSaveLosts = eaSaveLosts; eaExpert.eaSaveRestrictions = eaSaveRestrictions; // // Management Panel ... eaExpert.eaShowPanel = eaShowPanel; eaExpert.eaPanelAllowedTPSLStep = eaPanelAllowedTPSLStep; eaExpert.eaPanelMinAllowedRiskInPoint = eaPanelMinAllowedRiskInPoint; eaExpert.eaPanelRiskInPoint = eaPanelRiskInPoint; eaExpert.eaPanelRiskToRewardRatio = eaPanelRiskToRewardRatio; eaExpert.eaPanelVolume = eaPanelVolume; // // Attach Event Handlers ... eaExpert.AddOnSignalEventHandler(OnSignalTriggered); eaExpert.onGuardedEventHandler = OnGuardedTriggered; eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); eaExpert.AddOnSignalExecutedEventHandler(OnSignalExecuted); eaExpert.canAnalyseEventHandler = CanAnalyseEventTriggered; eaExpert.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); eaExpert.checkForGuardEventHandler = CheckForGuardTriggered; eaExpert.AddOnModifyPositionEventHandler(OnPositionModified); eaExpert.AddOnPositionsChangedEventHandler(OnPositionsChanged); eaExpert.AddOnTradeStateChangedEventHandler(OnTradeStateChanged); eaExpert.AddOnForceClosePositionEventHandler(OnPositionForceClosed); eaExpert.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed); // // Try to Initialize eaExpert ... bool isInited = eaExpert.HandleOnInit(); if (!isInited) { // Print(ShortName, ": Initialization Failed ..."); return INIT_FAILED; } // Print(ShortName, ": Initialized Successfully ..."); return INIT_SUCCEEDED; } /** * De Initialize Expert ... * * @param reason: int, DeInitialization Reason ... * * REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function * REASON_REMOVE 1 Program removed from a chart * REASON_RECOMPILE 2 Program recompiled * REASON_CHARTCHANGE 3 A symbol or a chart period is changed * REASON_CHARTCLOSE 4 Chart closed * REASON_PARAMETERS 5 Inputs changed by a user * REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings * REASON_TEMPLATE 7 Another chart template applied * REASON_INITFAILED 8 The OnInit() handler returned a non-zero value * REASON_CLOSE 9 Terminal closed * */ void OnDeinit(const int reason) { // // Destroy Timer ... // If Initialized ... // // De Init Expert Class Instance ... eaExpert.HandleOnDeInit(); // // Cleanup Resources ... delete eaExpert; ZeroMemory(eaExpert); } /** * Handle Tick for Processing ... */ void OnTick() { eaExpert.HandleOnTick(); } /** * Handle On Trade Processing ... */ void OnTrade() { eaExpert.HandleOnTrade(); } /** * Handle On Timer Processing ... */ void OnTimer() { eaExpert.HandleOnTimer(); } /** * Handle On Chart Event Processing ... * @param id: int, Specified Event ID ... * @param lparam: long, type event parameter * @param dparam: double, type event parameter * @param sparam: string, type event parameter */ void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam); } // // Event Listeners ... /** * Handle CanAnalyse Event Triggered ... * * @param symbol: Symbol ... * @param period: Period ... * @param time: Analysing Time ... * * @return ( bool ) */ bool CanAnalyseEventTriggered( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { return eaExpert.HandleCanAnalyseEventTriggered( symbol, period, time // ); } /** * Check For Guard ... * * @param guards: XGuard, reference Collection to holds result ... * @param positions: XPosition, refrence collection to Provides Positions ... * @param barIndex: int, Specified Bar index ... * * @return ( int ) */ int CheckForGuardTriggered( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ) { // return eaExpert.CheckForGuardTriggered( guards, positions, barIndex // ); } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void OnGuardedTriggered( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { eaExpert.OnGuardedTriggered(action, positions); } /** * Trigger OnSignal Event ... * * @param signal: XSignal */ void OnSignalTriggered(XSignal &signal) { eaExpert.HandleOnSignalTriggered(signal); } /** * Trigger OnSignal Executed Event ... * * @param signal: XSignal */ void OnSignalExecuted(XSignal &signal) { eaExpert.HandleOnSignalExecuted(signal); } /** * Handle StopLoss Triggered Positions ... * * @param deal: XDeal instance ... */ void OnStopLossTriggered(const XDeal &deal) { eaExpert.HandleOnStopLossTriggered(deal); } /** * Handle Take Profit Triggered Positions ... * * @param deal: XDeal instance ... */ void OnTakeProfitTriggered(const XDeal &deal) { eaExpert.HandleOnTakeProfitTriggered(deal); } /** * Handle Force Close a Position ... * * @param ticket: ULONG ... * @param position: XPosition instance ... * @param comment: String ... */ void OnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // eaExpert.HandleOnPositionForceClosed( ticket, position, comment // ); } /** * Handle Deals Changes ... * * @param count: Integer, Number of Changes ... */ void OnDealsChanged(int count) { eaExpert.HandleOnDealsChanged(count); } /** * Handle Orders Changes ... * * @param count: Integer, Number of Changes ... */ void OnOrdersChanged(int count) { eaExpert.HandleOnOrdersChanged(count); } /** * Handle Positions Changes ... * * @param count: Integer, Number of Changes ... */ void OnPositionsChanged(int count) { eaExpert.HandleOnPositionsChanged(count); } /** * Handle Position Modified ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionModified( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionModified( ticket, profit, comment // ); } /** * Handle Position Partial Closed ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionPartialClosed( ticket, profit, comment // ); } /** * Handle Trade State Changed ... * * @param state: XOnTradeHandlerState instance ... */ void OnTradeStateChanged(const XOnTradeHandlerState &state) { eaExpert.HandleOnTradeStateChanged(state); } // // Custom Functions ... /** * Validate all Inputs of Expert Adviser ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // string errMessage = ""; // bool isCommonValid = ( // eaSlippage > 0 && eaMagicNumber > 0 // ); if (!isCommonValid) { // errMessage += "common configurations error;" + "\n"; } // result = // // Common ... isCommonValid && // // Otere ... true // ; // if (!result) { // // Since here Logger not Initiallized, we Use Raw Print Command ... Print(ShortName + " Errors: \n", errMessage); } // return result; } /** * Initialize Timer ... * * @return ( bool ) */ bool InitTimer() { // bool result = false; // // TODO: Initialize Timer if necessary ... // result = EventSetTimer(1); // result = EventSetMillisecondTimer(100); result = true; // return result; } /** * Destroy Timer ... */ void DestroyTimer() { // // TODO: Use This ... // EventKillTimer(); } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Helpers\x-saherelm.x121.xcc.helper.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Helper Class Library // ---------------------------------------------- // Name: XSCX121XCCHelper // Description: provides all Indicator // Helper requirements ... // // // 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.x-helper.class.mq5" // // Definitions ... // // Input Models ... struct X121XCCInputs { // // Props ... // // Chart Style ... ENUM_CHART_MODE mode; // Mode color upColor; // Up Color color downColor; // Down Color color lineColor; // Line mode and Doji candlestick Color color bearishColor; // Bullish Color color bullishColor; // Bearish Color color volumesColor; // Volumes Color // // Presentation ... bool showCandles; // Show Candles // // Constructor(s) ... X121XCCInputs() { // Clean(); } // // Tools ... // // Clean ... void Clean() { // mode = CHART_CANDLES; // upColor = CLR_NONE; downColor = CLR_NONE; lineColor = CLR_NONE; bearishColor = CLR_NONE; bullishColor = CLR_NONE; volumesColor = CLR_NONE; // showCandles = false; // ZeroMemory(this); } // // Default ... void Default() { // mode = CHART_CANDLES; // upColor = clrLime; downColor = clrRed; lineColor = clrLime; bearishColor = clrRed; bullishColor = clrLime; volumesColor = clrGreen; // showCandles = true; } // // Hide all Visible Buffers ... void Hide() { showCandles = false; } // // Validate ... bool IsValid() { // bool result = false; // result = // true // ; // return result; } // // Retrieve MAx Length ... int Max() { // int result = 0; // result = MathMax(0, 0); // return result; } }; // // Class ... class XCX121XCCHelper : public XCBaseHelper { // // Public ... public: // // Props ... // // Constructors ... XCX121XCCHelper() : XCBaseHelper(_Symbol, _Period) { } // // Deconstructor ... ~XCX121XCCHelper() { mInputs.Clean(); } // // Tools ... bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period X121XCCInputs &inputs // Inputs ) { // bool result = false; // mSymbol = symbol; mPeriod = period; // result = inputs.IsValid(); if (!result) { return result; } // mInputs = inputs; // mHandler = iCustom( mSymbol, mPeriod, "x-saherelm.x121.xcc", // // Inputs ... // // Chart Style ... "", mInputs.mode, // Mode mInputs.upColor, // Up Color mInputs.downColor, // Down Color mInputs.lineColor, // Line mode and Doji candlestick Color mInputs.bullishColor, // Bearish Color mInputs.bearishColor, // Bullish Color mInputs.volumesColor, // Volumes Color // // Presentation ... "", mInputs.showCandles // Show Candles // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Inputs ... // X121XCCInputs GetInputs() { return mInputs; } // bool SetInputs( X121XCCInputs &inputs // Configs ) { // return Init( mSymbol, mPeriod, inputs // ); } // // Protected ... protected: // // Private ... private: // // Props ... X121XCCInputs mInputs; // Inputs ... }; // // Tools ... ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Helpers\x-saherelm.x121.xct.helper.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Helper Class Library // ---------------------------------------------- // Name: XSCX121XCTHelper // Description: provides all Indicator // Helper requirements ... // // // 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.x-helper.class.mq5" // // Definitions ... // // Input Models ... struct X121XCTInputs { // // Props ... // string font; // Font int fontSize; // Font Size; color clr; // Text Color ENUM_BASE_CORNER corner; // Text Position // // Presentation ... bool showCandleTime; // Show Candle Time // // Constructor(s) ... X121XCTInputs() { Clean(); } // // Tools ... // // Clean ... void Clean() { // font = NULL; fontSize = 15; clr = CLR_NONE; corner = CORNER_RIGHT_LOWER; // // Presentation ... showCandleTime = false; // ZeroMemory(this); } // // Default ... void Default() { // font = "Arial"; fontSize = 15; clr = clrYellow; corner = CORNER_RIGHT_LOWER; // // Presentation ... showCandleTime = true; } // // Hide all Visible Buffers ... void Hide() { showCandleTime = false; } // // Validate ... bool IsValid() { // bool result = false; // result = // true // ; // return result; } // // Retrieve MAx Length ... int Max() { // int result = 0; // result = MathMax(0, 0); // return result; } }; // // Class ... class XCX121XCTHelper : public XCBaseHelper { // // Public ... public: // // Props ... // // Constructors ... XCX121XCTHelper() : XCBaseHelper(_Symbol, _Period) { } // // Deconstructor ... ~XCX121XCTHelper() { mInputs.Clean(); } // // Tools ... bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period X121XCTInputs &inputs // Inputs ) { // bool result = false; // mSymbol = symbol; mPeriod = period; // result = inputs.IsValid(); if (!result) { return result; } // mInputs = inputs; // mHandler = iCustom( mSymbol, mPeriod, "x-saherelm.x121.xct", // // Inputs ... mInputs.fontSize, // Font Size ... mInputs.font, // Font ... mInputs.clr, // Text Color ... mInputs.corner, // Text Position ... // // Presentation ... "", mInputs.showCandleTime // Show Candle Time // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Inputs ... // X121XCTInputs GetInputs() { return mInputs; } // bool SetInputs( X121XCTInputs &inputs // Configs ) { // return Init( mSymbol, mPeriod, inputs // ); } // // Protected ... protected: // // Private ... private: // // Props ... X121XCTInputs mInputs; // Inputs ... }; // // Tools ... ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Indicators\x-saherelm.x121.xcc.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Candle Styles // --------------------------------------------------- // Name: X121 XCC // Description: Candle Styles ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121 XCC Indicator" #property icon "../Images/SaherElm_Logo_Color.ico" #property strict // // START Constants ... // // // Indicator Short Name ... #define ShortName "X121 XCC" // // Holds an SnapShot of Charts Configuration ... struct XChartStyle { // // chart's ID ... long chartId; // // chart's mode ... ENUM_CHART_MODE mode; // // show bid line ... bool showBidLine; // // show ask line ... bool showAskLine; // // show grids on chart ... bool showGrid; // // show volumes ... bool showVolumes; // // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... bool showTradeLevels; // // chart autoscroll ... bool autoScroll; // // chart quick navigation state ... bool quickNavigation; // // chart's foreground color ... color foreGroundColor; // // chart's background color ... color backGroundColor; // // Up Color ... color upColor; // // Down Color ... color downColor; // // Bullish color ... color bullishColor; // // Bearish color ... color bearishColor; // // grid color ... color gridColor; // // bid line color ... color bidLineColor; // // ask line color ... color askLineColor; // // line mode and doji candlestick color ... color lineColor; // // Color of stop order levels (Stop Loss and Take Profit) ... color stopColor; // // volumes color ... color volumesColor; }; // // END Constants ... // // // START Inputs ... // // input group "Chart Style"; input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode input color upColor = clrGreen; // Up Color input color downColor = clrRed; // Down Color input color lineColor = clrGreen; // Line mode and Doji candlestick Color input color bullishColor = clrGreen; // Bullish Color input color bearishColor = clrRed; // Bearish Color input color volumesColor = clrGreen; // Volumes Color // input group "Presentation"; input bool showCandles = true; // Show Candles // // END Inputs ... // // // START Includes and Imports ... // // // Includes Draw Library ... #include "../Libraries/x-saherelm.draw.lib.mq5" // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // END Includes and Imports ... // // // START Buffers ... // // #property indicator_chart_window // #property indicator_buffers 0 #property indicator_plots 0 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // // int maxLength; // XChartStyle chartStyle; XChartStyle clearStyle; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // drawPrefix = ShortName; // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... maxLength = ExtractMaxLengthOfInputs(); // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Apply Chart Style ... ApplyCustomChartStyle(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // // Prepare Buffers ... ArraySetAsSeries(time, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(spread, true); // // this counts Available Bars ... int limit; // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { CalculateBuffers(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = true; // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // return result; } // // Define Indexes and Styles ... void DefineBuffers() { } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // // Calculate Buffers ... void CalculateBuffers( int bar_index // Selected Bar Index ) { } // // Apply Custom Chart Style ... void ApplyCustomChartStyle() { // // Read Current Chart Config and Store it ... ReadChartStyle(); // // After Reading Current Chart Style ... // we have to Save Configs and Change Styles ... clearStyle = chartStyle; // clearStyle.upColor = CLR_NONE; clearStyle.downColor = CLR_NONE; clearStyle.lineColor = CLR_NONE; clearStyle.bullishColor = CLR_NONE; clearStyle.bearishColor = CLR_NONE; // // Decide to Show or not Candles based on User Input ... if (showCandles) { SetChartStyle(chartStyle); } else { SetChartStyle(clearStyle); } } // // Read Previous Chart Style ... void ReadChartStyle() { // // Retrieve Current Chart ID ... long chartId = ChartID(); chartStyle.chartId = chartId; // // Retrieve Chart Mode ... chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); // chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); // chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); // chartStyle.mode = mode; chartStyle.upColor = upColor; chartStyle.downColor = downColor; chartStyle.lineColor = lineColor; chartStyle.bearishColor = bearishColor; chartStyle.bullishColor = bullishColor; chartStyle.volumesColor = volumesColor; } // // Set Chart Style ... void SetChartStyle( XChartStyle &mChartStyle // Chart Style to Apply ) { // ApplyChartStyle( mChartStyle.chartId, mChartStyle.mode, mChartStyle.showBidLine, mChartStyle.showAskLine, mChartStyle.showGrid, mChartStyle.showVolumes, mChartStyle.showTradeLevels, mChartStyle.autoScroll, mChartStyle.quickNavigation, mChartStyle.foreGroundColor, mChartStyle.backGroundColor, mChartStyle.upColor, mChartStyle.downColor, mChartStyle.bullishColor, mChartStyle.bearishColor, mChartStyle.gridColor, mChartStyle.bidLineColor, mChartStyle.askLineColor, mChartStyle.lineColor, mChartStyle.stopColor, mChartStyle.volumesColor); } // // END Functions ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Indicators\x-saherelm.x121.xct.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // --------------------------------------------- // Name: X121 XCT // Description: Trend Magic Indicator ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121 XCT Indicator" #property icon "../Images/SaherElm_Logo_Color.ico" #property strict // // START Constants ... // // #define ShortName "X121 XCT" #include "../Libraries/x-saherelm.common.lib.mq5" // // END Constants ... // // // START Inputs ... // // input int fontSize = 15; // Font Size input string font = "Arial"; // Font input color clr = clrYellow; // Text Color input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position // input group "Presentation"; input bool showTimer = true; // Show Candle Time // // END Inputs ... // // // START Buffers ... // // #property indicator_chart_window // #property indicator_buffers 0 #property indicator_plots 0 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // bool isCreatedObject; string tag; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... // tag = ShortName + _Symbol + ToXString(_Period); // // Set Indicator ShortName ... SetIndicatorName(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // Delete Object ... ObjectDelete(0, tag); // Comment(""); } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // if (!showTimer) { return rates_total; } // XBarRemainsTime barRemains; barRemains.Init( _Symbol, _Period // ); // string msg = barRemains .ToString( "", "", "", "", "", ":", true // ); // long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); // string _sp = ""; if (mSpread < 10) _sp = ".."; else if (mSpread < 100) _sp = "."; // string objText = "Spread: " + IntegerToString(mSpread) + _sp + ", Next Bar in: " + msg; // if (IsValid(tag) && !isCreatedObject) { CreateIndicatorObject(); } // if (isCreatedObject) { ObjectSetString(0, tag, OBJPROP_TEXT, objText); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // void CreateIndicatorObject() { // if (!showTimer || !IsValid(tag)) { return; } // isCreatedObject = ObjectCreate(0, tag, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, tag, OBJPROP_CORNER, corner); ObjectSetInteger(0, tag, OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, tag, OBJPROP_YDISTANCE, 2); // ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; switch (corner) { case CORNER_LEFT_UPPER: Anchor = ANCHOR_LEFT_UPPER; break; case CORNER_RIGHT_UPPER: Anchor = ANCHOR_RIGHT_UPPER; break; case CORNER_LEFT_LOWER: Anchor = ANCHOR_LEFT_LOWER; break; case CORNER_RIGHT_LOWER: Anchor = ANCHOR_RIGHT_LOWER; break; } // int mFontSize = fontSize > 0 ? fontSize : 10; // string mFont = IsValid(font) ? font : "Arial"; // ObjectSetString(0, tag, OBJPROP_FONT, mFont); ObjectSetInteger(0, tag, OBJPROP_COLOR, clr); ObjectSetInteger(0, tag, OBJPROP_ANCHOR, Anchor); ObjectSetInteger(0, tag, OBJPROP_FONTSIZE, mFontSize); } // // END Functions ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.common.extensions.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XCommonExtensionsLib // Description: provide all commonly used functions ... // // // 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 // #include "../Classes/x-saherelm.x-md5.class.mq5" #include "../Libraries/x-saherelm.x-enums.lib.mq5" // #include // // Constants ... #define X_MIN_SIZE 0 #define X_INVALID_INDEX -1 // // START Value Checkers ... // // // Check a Value Not Empty ... template bool NotEmpty(T value) { return value != EMPTY_VALUE; } // // Check a Value Not Empty and Zero ... template bool NotEmptyZero(T value) { return value != 0 && value != EMPTY_VALUE; } // // END Value Checkers ... // // // START Validators ... // /** * Validate Strings ... * * @param value: string * * @return ( bool ) */ bool IsValid(string value) { // bool result = false; // result = // value != NULL && StringLen(value) > 0 // ; // return result; } bool IsXValid(string value) { return IsValid(value); } bool IsSpecifiedValid(string value) { return IsValid(value); } /** * Validate Date ... * * @param value: datetime * * @return ( bool ) */ bool IsValid(datetime value) { // bool result = false; // result = NotEmpty(value) && value != NULL; // return result; } bool IsXValid(datetime value) { return IsValid(value); } bool IsSpecifiedValid(datetime value) { return IsValid(value); } /** * Validate Time Frame ... * * @param value: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool IsValid(ENUM_TIMEFRAMES value) { // bool result = false; // result = // value != NULL // ; // return result; } bool IsXValid(ENUM_TIMEFRAMES value) { // return IsValid(value); } bool IsSpecifiedValid(ENUM_TIMEFRAMES value) { // return IsValid(value); } /** * Validate Specific Period Mode ... * * @param mMethod: ENUM_X_PERIOD_METHOD member, Period Select Method ... * @param mPeriod: ENUM_TIMEFRAMES member, Selected Period ... * * @return ( bool ) */ bool IsValid( ENUM_X_PERIOD_METHOD mMethod, ENUM_TIMEFRAMES mPeriod // ) { // bool result = false; // result = // mMethod == X_PERIOD_NONE ? false : mMethod == X_PERIOD_MANUALLY ? mPeriod != NULL : mMethod == X_PERIOD_AUTO ? true : false // ; // return result; } bool IsXValid( ENUM_X_PERIOD_METHOD mMethod, ENUM_TIMEFRAMES mPeriod // ) { return IsValid( mMethod, mPeriod // ); } bool IsSpecifiedValid( ENUM_X_PERIOD_METHOD mMethod, ENUM_TIMEFRAMES mPeriod // ) { return IsValid( mMethod, mPeriod // ); } /** * Validate a Size Value ... * * @param value: int, Provided Size ... * * @return ( bool ) */ bool IsValidSize(int value) { // bool result = value > X_MIN_SIZE; // return result; } /** * Check a Given Index is Valid or not ... * * @param value: int, Provided Index ... * * @return ( bool ) */ bool IsValidIndex(int value) { return value >= X_MIN_SIZE; } // // END Validators ... // // // START Normalizations ... // /** * Normalize Symbol ... * * @param value: string, Provided Symbols ... * * @return ( string ) */ string NormalizeSymbol(string value) { // string result = value; // if (!IsValid(result)) { result = _Symbol; } // return result; } /** * Normalize Time ... * * @param value: datetime, Provided Time ... * * @return ( datetime ) */ datetime NormalizeTime(datetime value) { // datetime result = value; // if (!IsValid(result)) { result = TimeCurrent(); } // return result; } /** * Normalize Period ... * * @param value: ENUM_TIMEFRAMES member, Provided Period ... * * @return ( ENUM_TIMEFRAMES ) */ ENUM_TIMEFRAMES NormalizePeriod(ENUM_TIMEFRAMES value) { // ENUM_TIMEFRAMES result = value; // if (!IsValid(value)) { result = _Period; } // return result; } /** * Normalize Market Cycle ... * * @param value: ENUM_X_MARKET_CYCLES, Provided Cycle ... * * @return ( ENUM_X_MARKET_CYCLES ) */ ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value) { // ENUM_X_MARKET_CYCLES result = value; // if (!IsValid(result)) { result = X_MARKET_CYCLE_SHORT; } // return value; } /** * Normalize Price Boundary ... * * @param value: ENUM_X_BOUNDARY_PRICE, Provided Boundary Mode ... * * @return ( ENUM_X_BOUNDARY_PRICE ) */ ENUM_X_BOUNDARY_PRICE NormalizeBoundary(ENUM_X_BOUNDARY_PRICE value) { // ENUM_X_BOUNDARY_PRICE result = value; // if (!IsValid(result)) { result = X_BOUNDARY_PRICE_HIGH_LOW; } // return result; } /** * Normalize Integer Value ... * * @param value: int, Provided Value ... * @param min: int, Minimum Allowed Value ... * @param max: int, Maximum Allowed Value ... * * @return ( int ) */ int NormalizeInt( int value, int min = 0, int max = INT_MAX // ) { // if (value < min) { value = min; } // if (value > max) { value = max; } // return value; } /** * Normalize Double Value ... * * @param value: double, Provided Value ... * @param min: double, Minimum Allowed Value ... * @param max: double, Maximum Allowed Value ... * * @return ( double ) */ double NormalizeDouble( double value, double min = 0, double max = DBL_MAX // ) { // if (value < min) { value = min; } // if (value > max) { value = max; } // return value; } double NormalizeXDouble( double value, double min = 0, double max = DBL_MAX // ) { return NormalizeDouble(value, min, max); } /** * Normalize Index based on Collection ... * * @param index: int, Provided Index ... * @param buffer: Collection Reference ... */ template bool NormalizeIndex( int &index, T &buffer[] // ) { // bool result = false; // int size = ArraySize(buffer); result = IsValidSize(size); if (!result) { return result; } // if (!IsValidIndex(index)) { index = X_MIN_SIZE; } // if (index > size - 1) { index = size - 1; } // result = IsValidIndex(index) && index >= X_MIN_SIZE && index < size; // return result; } /** * Normalize Start and Count based on Specified Buffer ... * * @param start: int, Provided Start index ... * @param count: int, Provided Number of Iteration ... * @param buffer: Collection instance ... */ template void NormalizeCount( int &start, int &count, T &buffer[] // ) { // // Validate Buffer Size ... int bufferSize = ArraySize(buffer); if (!IsValidSize(bufferSize)) { return; } // // Normalization Start ... NormalizeIndex( start, buffer // ); // if (count < start) { count = (start - count); } // // Normalization Count ... // if (count < 0) { count = start; } // if (count > bufferSize - start) { count = bufferSize - start; } } /** * Normalize a Volume ... * * @param mVolume: double, Provided Volume ... * @param mSymbol: string, Specified Symbol ... * @param mLength: int, Provided Default floating Length ... * * @return ( double ) */ double NormalizeVolume( double mVolume, string mSymbol = NULL, int mLength = 2 // ) { // double result = mVolume; // mSymbol = NormalizeSymbol(mSymbol); // double maxAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MAX); double minAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MIN); // // Normalize Digits ... int digits = GetDigits(minAvailableVolume); // mLength = mLength == 0 || mLength > digits ? digits : MathMin(mLength, digits); // // Normalize Volume ... result = NormalizeDouble(result, mLength); // // Validate Result ... if (result > maxAvailableVolume) { result = maxAvailableVolume; } else if (result < minAvailableVolume) { result = minAvailableVolume; } // return result; } /** * Normalize a Price Value ... * * @param mPrice: double, Provided Price ... * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ double NormalizePrice( double mPrice, string mSymbol = NULL // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // double tickSize = 0; result = SymbolInfoDouble(mSymbol, SYMBOL_TRADE_TICK_SIZE, tickSize); // int digits = GetDigits(mSymbol); result = NormalizeDouble(MathRound(mPrice / tickSize) * tickSize, digits); // return result; } /** * Normalize Chart Id ... * * @param _chartId: ulong * * @return ( ulong ) */ ulong NormalizeChartId(ulong _chartId = 0) { // if (_chartId <= 0) { _chartId = ChartID(); } // return _chartId; } // // END Normalizations ... // // // START Position ... // /** * Determine a Position type is Long or not ... * * @param value: ENUM_POSITION_TYPE member, Specified Type ... * * @return ( bool ) */ bool IsLong(ENUM_POSITION_TYPE value) { // bool result = value == POSITION_TYPE_BUY; // return result; } /** * Determine a Position type is Long or not ... * * @param value: ENUM_ORDER_TYPE member, Specified Type ... * * @return ( bool ) */ bool IsLong(ENUM_ORDER_TYPE value) { // bool result = value == ORDER_TYPE_BUY; // return result; } /** * Determine a Position type is Long or not ... * * @param value: ENUM_X_DIRECTION member, Specified Type ... * * @return ( bool ) */ bool IsLong(ENUM_X_DIRECTION value) { // bool result = value == X_DIRECTION_BULLISH; // return result; } /** * Determine a Position type is Short or not ... * * @param value: ENUM_POSITION_TYPE member, Specified Type ... * * @return ( bool ) */ bool IsShort(ENUM_POSITION_TYPE value) { // bool result = value == POSITION_TYPE_SELL; // return result; } /** * Determine a Position type is Short or not ... * * @param value: ENUM_ORDER_TYPE member, Specified Type ... * * @return ( bool ) */ bool IsShort(ENUM_ORDER_TYPE value) { // bool result = value == ORDER_TYPE_SELL; // return result; } /** * Determine a Position type is Short or not ... * * @param value: ENUM_X_DIRECTION member, Specified Type ... * * @return ( bool ) */ bool IsShort(ENUM_X_DIRECTION value) { // bool result = value == X_DIRECTION_BEARISH; // return result; } /** * Converts Opposit Direction Type ... * * @param value: ENUM_POSITION_TYPE member, Specified Type ... * * @return ( ENUM_POSITION_TYPE ) */ ENUM_POSITION_TYPE Opposit(ENUM_POSITION_TYPE value) { // ENUM_POSITION_TYPE result = NULL; // bool isLong = IsLong(value); result = isLong ? POSITION_TYPE_SELL : POSITION_TYPE_BUY; // return result; } /** * Converts Opposit Direction Type ... * * @param value: ENUM_ORDER_TYPE member, Specified Type ... * * @return ( ENUM_ORDER_TYPE ) */ ENUM_ORDER_TYPE Opposit(ENUM_ORDER_TYPE value) { // ENUM_ORDER_TYPE result = NULL; // bool isLong = IsLong(value); result = isLong ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; // return result; } /** * Converts To String ... * * @param value: ENUM_POSITION_TYPE member ... * * @return ( string ) */ string ToXString(ENUM_POSITION_TYPE value) { // string result = NULL; // result = // IsLong(value) ? "Long" : "Short" // ; // return result; } /** * Converts To String ... * * @param value: ENUM_ORDER_TYPE member ... * * @return ( string ) */ string ToXString(ENUM_ORDER_TYPE value) { // string result = NULL; // result = // IsLong(value) ? "Long" : "Short" // ; // return result; } /** * Get Ask Price ... * * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ double GetAsk( string mSymbol = NULL // ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_ASK); // return result; } /** * Get Bid Price ... * * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ double GetBid( string mSymbol = NULL // ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_BID); // return result; } /** * Get Spread Price ... * * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ double GetSpread( string mSymbol = NULL // ) { // mSymbol = NormalizeSymbol(mSymbol); // double ask = GetAsk(mSymbol); double bid = GetBid(mSymbol); // double result = MathAbs(ask - bid); // return result; } double GetXSpread( string mSymbol = NULL // ) { return GetSpread(mSymbol); } /** * Get SPecified Symbols Volume Step ... * * @param mSymbol: string ... * * @return ( double ) */ double GetVolumeStep( string mSymbol = NULL // ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_STEP); // return result; } /** * Get Point Price ... * * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ double GetPoints( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_POINT); // return result; } double GetXPoints(string mSymbol = NULL) { return GetPoints(mSymbol); } /** * Converts Price to Point ... * * @param price: double, price ... * @param mSymbol: string, Symbol ... * * @return ( double ) */ double PriceToPoint( double mPrice, // the price amount which required to calculate string mSymbol = NULL // Trading Symbol ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); mPrice = NormalizePrice(mPrice, mSymbol); // double point = GetPoints(mSymbol); result = mPrice / point; // return result; } /** * Get Digits Length ... * * @param mSymbol: string, Provided Symbol ... * * @return ( double ) */ int GetDigits( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // int result = (int)SymbolInfoInteger(mSymbol, SYMBOL_DIGITS); // return result; } /** * Get Entry Price ... * * @param mSymbol: string, Provided Symbol ... * @param type: ENUM_POSITION_TYPE member, Specified Entry type ... * * @return ( double ) */ double GetEntry( string mSymbol = NULL, ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? GetAsk(mSymbol) : GetBid(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } double GetXEntry( string mSymbol = NULL, ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // ) { return GetEntry(mSymbol, type); } /** * Get Entry Price ... * * @param mSymbol: string, Provided Symbol ... * @param type: ENUM_X_DIRECTION member, Specified Entry type ... * * @return ( double ) */ double GetEntry( string mSymbol = NULL, ENUM_X_DIRECTION type = X_DIRECTION_BULLISH // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsBullish(type) ? GetAsk(mSymbol) : GetBid(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } double GetXEntry( string mSymbol = NULL, ENUM_X_DIRECTION type = X_DIRECTION_BULLISH // ) { return GetEntry(mSymbol, type); } /** * Get Exit Price ... * * @param mSymbol: string, Provided Symbol ... * @param type: ENUM_POSITION_TYPE member, Specified Exit type ... * * @return ( double ) */ double GetExit( string mSymbol = NULL, ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? GetBid(mSymbol) : GetAsk(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } double GetXExit( string mSymbol = NULL, ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // ) { return GetExit(mSymbol, type); } /** * Get Exit Price ... * * @param mSymbol: string, Provided Symbol ... * @param type: ENUM_X_DIRECTION member, Specified Exit type ... * * @return ( double ) */ double GetExit( string mSymbol = NULL, ENUM_X_DIRECTION type = X_DIRECTION_BULLISH // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsBullish(type) ? GetBid(mSymbol) : GetAsk(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } double GetXExit( string mSymbol = NULL, ENUM_X_DIRECTION type = X_DIRECTION_BULLISH // ) { return GetExit(mSymbol, type); } /** * Retrieve Current Tick ... */ bool GetTick( string mSymbol, MqlTick &tick // ) { return SymbolInfoTick(mSymbol, tick); } // // Peak and Vales ... int FindXSwing( ENUM_X_SWING_TYPE mType, string mSymbol = NULL, ENUM_TIMEFRAMES mPeriod = NULL, int mFromIndex = 0, int mShoulders = 5 // ) { // int result = -1; // // Validate ... if (!IsXValid(mType)) { return result; } // result = mFromIndex; int foundedIDX = FindXNextSwing( mType, mSymbol, mPeriod, result - mShoulders, mShoulders * 2 + 1 // ); while (foundedIDX != result) { // result = FindXNextSwing( mType, mSymbol, mPeriod, result + 1, mShoulders // ); // foundedIDX = FindXNextSwing( mType, mSymbol, mPeriod, result - mShoulders, mShoulders * 2 + 1 // ); } // return result; } int FindXNextSwing( ENUM_X_SWING_TYPE mType, string mSymbol = NULL, ENUM_TIMEFRAMES mPeriod = NULL, int mFromIndex = 0, int mShoulders = 5 // ) { // int result = -1; // if (mFromIndex < 0) { mShoulders += mFromIndex; } // // Normalize ... mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); mFromIndex = NormalizeInt(mFromIndex, 0); mShoulders = NormalizeInt(mShoulders, 3); // // Validate .... if (!IsXValid(mType)) { return result; } // // Converts Swing Type to Series Mode ... ENUM_SERIESMODE mMode = ToSeriesMode(mType); result = mMode == MODE_HIGH ? iHighest( mSymbol, mPeriod, mMode, mShoulders, mFromIndex // ) : iLowest( mSymbol, mPeriod, mMode, mShoulders, mFromIndex // ); // return result; } // // END Position ... // // // START Tools ... // /** * Check Expert Running in Testing Mode or not ... * * @return ( bool ) */ bool IsRunningOnTestMode() { // bool result = false; // // check programm mode ... result = MQLInfoInteger(MQL_TESTER); // return result; } /** * Check Expert Running in Visual Testing Mode ... * * @return ( bool ) */ bool IsRunningeOnTestVisualMode() { // bool result = false; // result = IsRunningOnTestMode() && MQLInfoInteger(MQL_VISUAL_MODE); // return result; } /** * Find Chart ID ... * * @param mSymbol: string, Specified Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Specified Period ... * * @return ( long ) */ long FindChartID( string mSymbol = NULL, ENUM_TIMEFRAMES mPeriod = NULL // ) { // long result = ChartFirst(); long first = result; // while (result > 0) { // string chSymbol = ChartSymbol(result); ENUM_TIMEFRAMES chPeriod = ChartPeriod(result); // bool isOwn = // chSymbol == mSymbol && chPeriod == mPeriod // ; if (isOwn) { break; } // result = ChartNext(result); } // return result; } /** * Retrieve Available Symbols ... * * @param symbols: string Collection reference to Hold Symbols ... * @param onlyInWatchList: bool, Force Extracts only Watch List Symbols ... * * @return ( int ) */ int GetAllSymbols( string &symbols[], // Hold Result bool onlyInWatchList = false // Specified Retrieve only Symbols which in Watch List ) { // int result = 0; // Clean(symbols); // int count = SymbolsTotal(onlyInWatchList); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // string iSymbol = SymbolName( i, onlyInWatchList // ); if (!IsValid(iSymbol)) { continue; } // Add( iSymbol, symbols // ); } // result = ArraySize(symbols); // return result; } /** * Filter Symbols Collections ... * * @param query: string, Provided Query to Search Symbols ... * @param symbols: string, Collection resources to Hold's Filtered results ... * @param onlyInWatchList: bool, Specified Apply Filter only on Watch List Symbols ... * @param ignoreCase: bool, Ignore Case Sesitive ... * @param querySeparator: string, Provided Separator of Query ... * * @return ( int ) */ int FilterSymbols( string query, string &symbols[], bool onlyInWatchList = false, bool ignoreCase = true, string querySeparator = "," // If Provided means query is a Collection of Queries and need to be Splitted ) { // int result = 0; // Clean(symbols); // if (!IsValid(query)) { return result; } // // Check Query is an String array or not ... string mQueries[]; int queriesCount = 0; if (IsValid(querySeparator) && Contains(querySeparator, query, true)) { // queriesCount = SplitContent( mQueries, query, querySeparator // ); } // string allSymbols[]; int allSymbolsCount = GetAllSymbols( allSymbols, onlyInWatchList // ); if (allSymbolsCount <= 0) { return result; } // // Loop Through all Symbols ... for (int i = 0; i < allSymbolsCount; i++) { // string iSymbol = allSymbols[i]; // bool isFilterPassed = false; if (queriesCount == 0) { // isFilterPassed = Contains( query, iSymbol, ignoreCase // ); } else if (queriesCount > 0) { // isFilterPassed = Contains( mQueries, iSymbol, ignoreCase // ); } // if (isFilterPassed) { // Add( iSymbol, symbols // ); } } // result = ArraySize(symbols); // return result; } /** * Extract Symbols to Find Only USD Side Assets ... * * @param symbols: string, Collection resources to Hold's Filtered results ... * @param onlyInWatchList: bool, Specified Apply Filter only on Watch List Symbols ... * @param ignoreCase: bool, Ignore Case Sesitive ... * @param querySeparator: string, Provided Separator of Query ... * * @return ( int ) */ int FilterUSDSymbols( string &symbols[], bool onlyInWatchList = false, bool ignoreCase = true, string querySeparator = "," // ) { // return FilterSymbols( "USD", symbols, onlyInWatchList, ignoreCase, querySeparator // ); } /** * Get Digits Length of Specified Double Value ... * * @param value: double, Provided Value ... * * @return ( int ) */ int GetDigits(double value) { // int d = 0; double p = 1; while (MathRound(value * p) / p != value) { p = MathPow(10, ++d); } // return d; } /** * Retrieve Specific Object Types Name ... * * @param t: T object reference ... * * @return ( string ) * */ template string GetTypeName(const T &t) { return typename(T); } template string GetTypeName(const T *t) { return typename(T); } /** * Get Specified Types Token ... * * @param item: T, object reference ... * * @return ( string ) */ template string GetToken(T &item) { // string mType = GetTypeName(item); // string result = mType; // string parts[]; int partsCount = SplitContent( parts, result, " " // ); if (partsCount <= 0) { // result = mType; return result; } // bool hasLastPart = GetLastItem( result, parts // ); if (!hasLastPart) { // result = mType; return result; } // return result; } template string GetSpecificToken(T &item) { return GetToken(item); } /** * Generate Unique Tags ... * * @param model: T, object reference ... * * @return ( string ) */ template string GenerateTag(T &model) { // string result = ""; // string tag = model.ToXString(); if (StringLen(tag) == 0) { return result; } // XSCMD5 *md5; md5 = new XCMD5(); // result = md5.Hash(tag); // ZeroMemory(md5); // return result; } /** * Hash Specified Content ... * * @param content: T, Proveded Content ... * * @return ( string ) */ template string ToMD5(T content) { // string result = ""; // string strContent = ToXString(content); if (StringLen(strContent) == 0) { return result; } // XCMD5 *md5; md5 = new XCMD5(); // result = md5.Hash(strContent); // delete md5; ZeroMemory(md5); // return result; } /** * Calculate Fibo Level ... * * @param mUp: double, Specified Upper Price ... * @param mDown: double, Specified Lower Price ... * @param mLevel: ENUM_X_FIBO_LEVELS member, Specified Fibo Level ... * @param mForDir: ENUM_X_DIRECTION member, Specified Calculation Direction ... * * @return ( double ) */ double GetFibonacciLevel( double mUp, double mDown, ENUM_X_FIBO_LEVELS mLevel, ENUM_X_DIRECTION mForDir // ) { // double result = 0; // double levelValue = GetFiboLevelValue(mLevel); // bool isValid = // mUp > 0 && mDown > 0 && levelValue > 0 && mUp > mDown && HasDirection(mForDir) // ; if (!isValid) { return result; } // bool isBullish = IsBullish(mForDir); // double ling = mUp - mDown; double pLevel = (ling / 100) * (levelValue * 100); // result = isBullish ? mUp - pLevel : mDown + pLevel; // return result; } /** * Calculate Sspecified Buffer's Moving Averages ... * * @param rates_total: Integer, number of items ... * @param prev_calculated: Integer, Previous Calculate Items ... * @param begin: Integer, Bar Index ... * @param period: Integer, Moving Average Length ... * @param source: Double Array, Specified Array for Calculating Moving Averages ... * @param buffer: Double Array, Specified Array to Apply Calculated Moving Average on it ... * @param method: ENUM_MA_METHOD member Specified Moving Average Calculation Method ... * * @return ( int ) */ int iMAOnBuffer( const int _rates_total, const int _prev_calculated, const int _begin, const int _period, const double &_source[], double &_buffer[], ENUM_X_MA_METHOD _method = X_MA_MODE_SMA // ) { // int result = 0; // if ( _period < 0 || _rates_total <= 0 || _prev_calculated < 0 || _method == X_MA_MODE_NONE || _prev_calculated > _rates_total) { return result; } // switch (_method) { // case X_MA_MODE_SMA: result = SimpleMAOnBuffer( _rates_total, _prev_calculated, _begin, _period, _source, _buffer // ); break; // case X_MA_MODE_EMA: result = ExponentialMAOnBuffer( _rates_total, _prev_calculated, _begin, _period, _source, _buffer // ); break; // case X_MA_MODE_LWMA: result = LinearWeightedMAOnBuffer( _rates_total, _prev_calculated, _begin, _period, _source, _buffer // ); break; // case X_MA_MODE_SMMA: result = SmoothedMAOnBuffer( _rates_total, _prev_calculated, _begin, _period, _source, _buffer // ); break; } // return result; } // // END Tools ... // // // START String ... // /** * Search a Content Contains Specific String or not ... * * @param mQuery: string, Search Query ... * @param mContent: string, Search Content ... * @param ignoreCase: bool, Force Ignore Case Sensitive ... * * @return ( bool ) */ bool Contains( string mQuery, string mContent, bool ignoreCase = true // ) { // bool result = false; // // Validate Query ... result = IsValid(mQuery); if (!result) { return result; } // // Validate Content ... result = IsValid(mContent); if (!result) { return result; } // // Normalize Inputs ... string query = mQuery; string content = mContent; if (ignoreCase) { // StringToLower(query); StringToLower(content); } // int queryIdx = StringFind( content, query); // result = queryIdx >= 0; // return result; } /** * Search a Content Contains Specifics Query or not ... * * @param mQueries: string collection, Search Queries ... * @param mContent: string, Search Content ... * @param ignoreCase: bool, Force Ignore Case Sensitive ... * * @return ( bool ) */ bool Contains( string &mQueries[], string mContent, bool ignoreCase = true // ) { // bool result = false; // // Validate Queries ... int queriesCount = ArraySize(mQueries); result = queriesCount > 0; if (!result) { return result; } // // Validate Content ... result = IsValid(mContent); if (!result) { return result; } // int containsCount = 0; for (int i = 0; i < queriesCount; i++) { // bool isContains = Contains( mQueries[i], mContent, ignoreCase); // if (!isContains) { // result = false; break; } // containsCount++; } // result = containsCount == queriesCount; // return result; } /** * Search a Content and Extract Occuranse Indexes ... * * @param mQuery: string, Search Query ... * @param mContent: string, Search Content ... * @param result: int collection reference, Holds Founded Indexes ... * @param ignoreCase: bool, Force Ignore Case Sensitive ... * * @return ( int ) */ int FindIndexes( string mQuery, string mContent, int &result[], bool ignoreCase = false // ) { // int mResult = 0; // Clean(result); // // Validate Inputs ... if (!IsValid(mQuery) || !IsValid(mContent)) { return mResult; } // // Apply Ignore Case if Provided ... if (ignoreCase) { // bool isConverted = StringToLower(mQuery); if (!isConverted) { return mResult; } // isConverted = StringToLower(mContent); if (!isConverted) { return mResult; } } // // Search First Index ... int lastPos = 0; int idx = StringFind( mContent, mQuery, lastPos // ); while (idx >= 0) { // // Add Position to Result ... Add( idx, result // ); // lastPos = idx + StringLen(mQuery); idx = StringFind( mContent, mQuery, lastPos // ); } // mResult = ArraySize(result); // return mResult; } int FindXIndexes( string mQuery, string mContent, int &result[], bool ignoreCase = false // ) { return FindXIndexes(mQuery, mContent, result, ignoreCase); } /** * Convert From String ... * * @param value: string, Provided Value ... * * @return ( T ) */ template T FromString(string value) { // T result = NULL; // if (!IsValid(value)) { return result; } // result = (T)value; // return result; } /** * Converts to String ... * * @param value: T, Provided Value ... * * @return ( string ) */ template string ToXString(T value) { return (string)value; } string Trim(string value) { // string result = NULL; // result = value; // StringTrimRight(result); StringTrimLeft(result); // return result; } // // Used In Report or Summary Generators ... string ToXString( string prefix, // Title bool value, // Value bool ignoreFalseConditions = true, // Ignore False Conditions string lineSeparator = "\n", // Line Separator string prefixSeparator = ":" // Title Separator ) { // string result = NULL; // bool canSet = IsBoolean(ToXString(value)) ? (bool)value || !ignoreFalseConditions : true; // result = canSet ? prefix + prefixSeparator + " " + ToXString(value) + lineSeparator : ""; // return result; } // template string ToXString( string prefix, // Title T value, // Value string lineSeparator = "\n", // Line Separator string prefixSeparator = ":" // Title Separator ) { // string result = NULL; // result = prefix + prefixSeparator + " " + ToXString(value) + lineSeparator; // return result; } // string SetLabel( string mLabel, // Provided Label ... string value, // Source Value ... string separator = "\n", // Line Separator bool addTopEmptyLine = true // Add Empty Line On top ) { // string result = value; // if (StringLen(mLabel) <= 0) { return result; } // result = (StringLen(value) > 0) ? (addTopEmptyLine ? separator : "") + mLabel + separator + "-----------------------------" + separator + value : value; // return result; } // // Converts a Buffer to String Representation ... template string ToXString( const T &buffer[], // Specified Buffer string separator = ",", // Specified Separator bool addIndex = false, // Specified Add Items Indexes or Not string indexLabel = "i:", // Specified Index Label string indexSeparator = ">" // Specified Index Separator ) { // string result = ""; // int bufferSize = ArraySize(buffer); if (bufferSize <= 0) { return result; } // for (int i = 0; i < bufferSize; i++) { // if (addIndex) { // if (StringLen(indexLabel) > 0) { result += indexLabel + " "; } // result += (string)i + " "; // if (StringLen(indexSeparator) > 0) { result += indexSeparator + " "; } } // string iItemString = (string)buffer[i]; // result += iItemString; // if (i < bufferSize - 1) { result += separator; } } // return result; } /** * Check a String Value is Boolean or Not ... * * @param value: string representation of value ... * * @return ( bool ) */ bool IsBoolean(string value) { // bool result = false; // string istring = value; string normalizedValue = ToXString(istring); StringToLower(normalizedValue); normalizedValue = Trim(normalizedValue); // result = !IsValid(normalizedValue) ? false : (normalizedValue == "true" || normalizedValue == "false"); // return result; } /** * Converts String to boolean ... * * @param value: string, Provided Value ... * * @return ( bool ) */ bool ToBoolean(string value) { // bool result = false; // if (!IsBoolean(value) || StringLen(value) <= 0) { return result; } // value = Trim(value); StringToLower(value); // bool isTrue = value == "true"; bool isFalse = value == "false"; // result = isTrue ? true : false; // return result; } // // Split an String Representation of an Array ... int SplitContent( string &result[], // Hold Result ... string content, // Source ... string separator = ",", // Separator ... bool forceCleanResult = true // Clean Result ... ) { // int mResult = 0; // if (forceCleanResult) { Clean(result); } // int before = ArraySize(result); // if (separator == NULL || StringLen(separator) == 0) { separator = ","; } // if (StringLen(content) == 0) { return mResult; } // StringSplit( content, StringGetCharacter( separator, 0), result); // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Extract Data from String ... string ExtractString( const string source, // Source String used for Extracting const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // string result = ""; // // Validate String ... if ( StringLen(source) == 0 || StringLen(endString) == 0 || StringLen(startString) == 0) { return result; } // // Find Start String Position ... int sPos = StringFind( source, startString); if (sPos < 0) { return result; } // // Find End String Position after Start String ... int searchEndFromPos = sPos + StringLen(startString); int ePos = StringFind( source, endString, searchEndFromPos); if (ePos < 0) { return result; } // // Extract Data from Source ... int dLength = ePos - searchEndFromPos; result = StringSubstr( source, searchEndFromPos, dLength); // return result; } // // Extract an Array of Contents ... int ExtractStrings( string &result[], // Hold Result const string source, // Source String used for Extracting const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // int mResult = 0; // Clean(result); // // Validate Args ... int sourceLength = StringLen(source); int startLength = StringLen(startString); int endLength = StringLen(endString); // int minRequiredLength = startLength + endLength; // if ( endLength <= 0 || startLength <= 0 || sourceLength <= 0 || sourceLength < minRequiredLength) { return mResult; } // // Make a Copy of Source for Manipulating ... string workStr = source; // // Define a Loop ... while (StringLen(workStr) > minRequiredLength) { // // Find Item ... string item = ExtractString( workStr, startString, endString); // // Breakout when couldn't find anymore item ... int itemLength = StringLen(item); if (itemLength <= 0) { break; } // // Prepare Item Source String for Replacing in Work String ... string itemSource = startString + item + endString; // // Add Item to Result Array ... Add( item, result); // // Replace Item Soure in Work String ... StringReplace( workStr, itemSource, ""); } // // Calculate Size of Array ... mResult = ArraySize(result); // return mResult; } // string ExtractSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // return ExtractString( surrounded, mToken + startString, endString // ); } // int ParseIntSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // int result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (int)strContent; // return result; } long ParseLongSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // long result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (long)strContent; // return result; } string ParseStringSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // string result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (string)strContent; // return result; } double ParseDoubleSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // double result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (double)strContent; // return result; } datetime ParseTimeSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // datetime result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (datetime)strContent; // return result; } // int ParseIntArraySurrounded( int &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // int iValue = (int)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseLongArraySurrounded( long &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // long iValue = (long)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseDoubleArraySurrounded( double &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // double iValue = (double)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseTimeArraySurrounded( datetime &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // datetime iValue = (datetime)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } // // Surround an String by Specific Token ... template string Surround( string mToken, // an String which used to Tokenize T &value, // a Value for Tokenize it string startString = "(", // Token Start Content string endString = ")" // Token End Content ) { // string result = NULL; // string strValue = ToXString(value); if (!IsValid(strValue)) { return result; } // result = // (IsValid(mToken) ? mToken : "") + // startString + strValue + endString // ; // return result; } // template string SurroundArray( string mToken, T &value[], string startString = "(", // Token Start Content string endString = ")" // Token End Content ) { // string result = NULL; // string valueStr = ToXString(value); if (!IsValid(valueStr)) { return result; } // result = Surround( mToken, valueStr, startString, endString // ); // return result; } // // END String ... // // // START Cycles ... // /** * Converts String To Period ... * * @param value: string ... * * @return ( ENUM_TIMEFRAMES ) */ ENUM_TIMEFRAMES ToPeriod(string value) { // if (StringLen(value) == 0) { return _Period; } // StringTrimLeft(value); StringTrimRight(value); // ENUM_TIMEFRAMES result = _Period; // if (value == "M1") { result = PERIOD_M1; } else if (value == "M2") { result = PERIOD_M2; } else if (value == "M3") { result = PERIOD_M3; } else if (value == "M4") { result = PERIOD_M4; } else if (value == "M5") { result = PERIOD_M5; } else if (value == "M6") { result = PERIOD_M6; } else if (value == "M10") { result = PERIOD_M10; } else if (value == "M12") { result = PERIOD_M12; } else if (value == "M15") { result = PERIOD_M15; } else if (value == "M20") { result = PERIOD_M20; } else if (value == "M30") { result = PERIOD_M30; } else if (value == "H1") { result = PERIOD_H1; } else if (value == "H2") { result = PERIOD_H2; } else if (value == "H3") { result = PERIOD_H3; } else if (value == "H4") { result = PERIOD_H4; } else if (value == "H6") { result = PERIOD_H6; } else if (value == "H8") { result = PERIOD_H8; } else if (value == "H12") { result = PERIOD_H12; } else if (value == "D1") { result = PERIOD_D1; } else if (value == "W1") { result = PERIOD_W1; } else if (value == "MN1") { result = PERIOD_MN1; } // return result; } /** * Converts To String ... * * @param value: ENUM_TIMEFRAMES member ... * * @return ( string ) */ string ToXString(ENUM_TIMEFRAMES value) { // string result = ""; // string mPStr = EnumToString(value); string mPStrParts[]; int partsCount = StringSplit( mPStr, StringGetCharacter("_", 0), mPStrParts); if (partsCount <= 0) { return result; } // result = mPStrParts[1]; // return result; } // // Retrieve All Available Period as an Array ...s int GetAllAvailablePeriods( ENUM_TIMEFRAMES &result[] // Holds Result ... ) { // Clean(result); // Add( PERIOD_M1, result // ); // Add( PERIOD_M2, result // ); // Add( PERIOD_M3, result // ); // Add( PERIOD_M4, result // ); // Add( PERIOD_M5, result // ); // Add( PERIOD_M6, result // ); // Add( PERIOD_M10, result // ); // Add( PERIOD_M12, result // ); // Add( PERIOD_M15, result // ); // Add( PERIOD_M20, result // ); // Add( PERIOD_M30, result // ); // Add( PERIOD_H1, result // ); // Add( PERIOD_H2, result // ); // Add( PERIOD_H3, result // ); // Add( PERIOD_H4, result // ); // Add( PERIOD_H6, result // ); // Add( PERIOD_H8, result // ); // Add( PERIOD_H12, result // ); // Add( PERIOD_D1, result // ); // Add( PERIOD_W1, result // ); // Add( PERIOD_MN1, result // ); // int mResult = ArraySize(result); // return mResult; } // // Get Specific Time Frame Start Candle Time ... datetime GetPeriodStartTime( string mSymbol = NULL, // Specified Symbol ... ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... datetime mTime = NULL // Specified Bar Time of Host Period ... ) { // // Normalize Arg ... mTime = NormalizeTime(mTime); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int barIndex = iBarShift( mSymbol, mPeriod, mTime, false // ); // datetime result = GetBarTime( mSymbol, mPeriod, barIndex // ); // return result; } // // Retrieve Nearest Period base on Given Period ... ENUM_TIMEFRAMES GetNearestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: case PERIOD_M3: result = PERIOD_M5; break; // case PERIOD_M4: case PERIOD_M5: case PERIOD_M6: result = PERIOD_M10; break; // case PERIOD_M10: case PERIOD_M12: case PERIOD_M15: result = PERIOD_M20; break; // case PERIOD_M20: case PERIOD_M30: result = PERIOD_H1; break; // case PERIOD_H1: case PERIOD_H2: result = PERIOD_H3; break; // case PERIOD_H3: result = PERIOD_H4; break; // case PERIOD_H4: result = PERIOD_H6; break; // case PERIOD_H6: result = PERIOD_H8; break; // case PERIOD_H8: result = PERIOD_H12; break; // default: result = mPeriod; break; } // return result; } // // Retrieve Mediest Period base on Given Period ... ENUM_TIMEFRAMES GetMediestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: case PERIOD_M3: result = PERIOD_M10; break; // case PERIOD_M4: case PERIOD_M5: case PERIOD_M6: result = PERIOD_M15; break; // case PERIOD_M10: case PERIOD_M12: case PERIOD_M15: result = PERIOD_M30; break; // case PERIOD_M20: case PERIOD_M30: result = PERIOD_H2; break; // case PERIOD_H1: case PERIOD_H2: result = PERIOD_H4; break; // case PERIOD_H3: result = PERIOD_H6; break; // case PERIOD_H4: result = PERIOD_H8; break; // case PERIOD_H6: result = PERIOD_H12; break; // case PERIOD_H8: result = PERIOD_D1; break; // default: result = mPeriod; break; } // return result; } // // Retrieve Longest Period base on Given Period ... ENUM_TIMEFRAMES GetLongestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: case PERIOD_M3: result = PERIOD_M30; break; // case PERIOD_M4: case PERIOD_M5: case PERIOD_M6: result = PERIOD_H1; break; // case PERIOD_M10: case PERIOD_M12: case PERIOD_M15: result = PERIOD_H2; break; // case PERIOD_M20: case PERIOD_M30: result = PERIOD_H4; break; // case PERIOD_H1: case PERIOD_H2: result = PERIOD_H6; break; // case PERIOD_H3: result = PERIOD_H8; break; // case PERIOD_H4: result = PERIOD_H12; break; // case PERIOD_H6: result = PERIOD_D1; break; // case PERIOD_H8: result = PERIOD_W1; break; // default: result = mPeriod; break; } // return result; } // // Retrieve Hindmost Period base on Given Period ... ENUM_TIMEFRAMES GetHindMostPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: case PERIOD_M3: result = PERIOD_H1; break; // case PERIOD_M4: case PERIOD_M5: case PERIOD_M6: result = PERIOD_H2; break; // case PERIOD_M10: case PERIOD_M12: case PERIOD_M15: result = PERIOD_H4; break; // case PERIOD_M20: case PERIOD_M30: result = PERIOD_H6; break; // case PERIOD_H1: case PERIOD_H2: result = PERIOD_H8; break; // case PERIOD_H3: result = PERIOD_H12; break; // case PERIOD_H4: result = PERIOD_D1; break; // case PERIOD_H6: result = PERIOD_W1; break; // case PERIOD_H8: result = PERIOD_MN1; break; // default: result = mPeriod; break; } // return result; } // // Retrieve Specified Cycles Period related to Host Period ... ENUM_TIMEFRAMES GetCyclePeriod( ENUM_X_MARKET_CYCLES mCycle = NULL, // Specified Cycle ENUM_TIMEFRAMES mPeriod = NULL // Host Period ) { // ENUM_TIMEFRAMES result = NULL; // mPeriod = NormalizePeriod(mPeriod); mCycle = NormalizeCycle(mCycle); // switch (mCycle) { // // Short ... case X_MARKET_CYCLE_SHORT: result = GetNearestPeriod(mPeriod); break; // // Medium ... case X_MARKET_CYCLE_MEDIUM: result = GetMediestPeriod(mPeriod); break; // // Long ... case X_MARKET_CYCLE_LONG: result = GetLongestPeriod(mPeriod); break; // // Hind ... case X_MARKET_CYCLE_HIND: result = GetHindMostPeriod(mPeriod); break; } // return result; } // // Calculate a Cycle Length based on Host Period ... int GetCycleLengthOn( ENUM_TIMEFRAMES _hostPeriod, ENUM_X_MARKET_CYCLES _cycle, ENUM_X_PERIOD_METHOD _method, ENUM_TIMEFRAMES _period // ) { // int result = 0; // // Validate ... bool isValid = // IsValid(_hostPeriod) && IsValid(_method, _Period) // ; if (!isValid) { return result; } // // Calculate Period ... isValid = _method != X_PERIOD_NONE && _cycle != X_MARKET_CYCLE_UNKNOWN; if (!isValid) { return result; } // if (_method == X_PERIOD_AUTO) { // _period = GetCyclePeriod( _cycle, _hostPeriod // ); } isValid = IsValid(_period); if (!isValid) { return result; } // int _hostPeriodSeconds = PeriodSeconds(_hostPeriod); int _periodSeconds = PeriodSeconds(_period); // isValid = _periodSeconds >= _hostPeriodSeconds; if (!isValid) { return result; } // result = _periodSeconds / _hostPeriodSeconds; // return result; } /** * Retrieve Sharp Change Info for Specified Period ... * * @param priceChange: double, required Price Change ... * @param mPeriod: ENUM_TIMEFRAMES member, Specified Period ... * * @return ( int ) */ int GetPeriodSharpData( double &priceChange, ENUM_TIMEFRAMES mPeriod = NULL // ) { // int result = 0; // priceChange = 0.0; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: // priceChange = 0.000006; result = 14; break; // case PERIOD_M2: // priceChange = 0.000006; result = 14; break; // case PERIOD_M3: // priceChange = 0.00007; result = 14; break; // case PERIOD_M4: // priceChange = 0.000007; result = 14; break; // case PERIOD_M5: // priceChange = 0.000009; result = 14; break; // case PERIOD_M6: // priceChange = 0.000009; result = 14; break; // case PERIOD_M10: // priceChange = 0.00001; result = 12; break; // case PERIOD_M12: // priceChange = 0.000011; result = 11; break; // case PERIOD_M15: // priceChange = 0.000011; result = 9; break; // case PERIOD_M20: // priceChange = 0.000012; result = 9; break; // case PERIOD_M30: // priceChange = 0.000012; result = 7; break; // case PERIOD_H1: // priceChange = 0.000013; result = 5; break; // case PERIOD_H2: // priceChange = 0.000013; result = 5; break; // case PERIOD_H3: // priceChange = 0.000014; result = 5; break; // case PERIOD_H4: // priceChange = 0.000014; result = 5; break; // case PERIOD_H6: // priceChange = 0.000015; result = 5; break; // case PERIOD_H8: // priceChange = 0.000017; result = 5; break; // case PERIOD_H12: // priceChange = 0.000017; result = 5; break; // case PERIOD_D1: // priceChange = 0.000019; result = 3; break; // case PERIOD_W1: // priceChange = 0.00002; result = 3; break; // case PERIOD_MN1: // priceChange = 0.000021; result = 3; break; } // return result; } // // END Cycles ... // // // START Collections ... // // // Add Specified Item to Array ... template int Add( T item, // item want to add T &buffer[] // Destination buffer ) { // int result = 0; // ArrayResize( buffer, ArraySize(buffer) + 1); // buffer[ArraySize(buffer) - 1] = item; // result = ArraySize(buffer); // return result; } template int AddSpecified( T item, // item want to add T &buffer[] // Destination buffer ) { // return Add( item, buffer // ); } template int AddRef( T &item, // item want to add T &buffer[] // Destination buffer ) { // int result = 0; // ArrayResize( buffer, ArraySize(buffer) + 1); // buffer[ArraySize(buffer) - 1] = item; // result = ArraySize(buffer); // return result; } // // Check Specified Array Has Childs or not ... template bool HasChild(T &buffer[]) { return IsValidSize(ArraySize(buffer)); } template bool SpecifiedHasChild(T &buffer[]) { return HasChild(buffer); } // // Remove Specified Item from an Array ... template bool Remove( T item, T &buffer[] // ) { // bool result = false; // int itemIndex = FindIndex( item, buffer); if (itemIndex < 0) { return result; } // result = ArrayRemove( buffer, itemIndex, 1); // return result; } // // Clean Specified Array ... template void Clean(T &buffer[]) { // if (!HasChild(buffer)) { return; } // // ArrayResize(buffer, 0); ArrayFree(buffer); ZeroMemory(buffer); } template void SpecifiedClean(T &buffer[]) { Clean(buffer); } template void XClean(T &buffer[]) { Clean(buffer); } // // Copy Whole Content of Source to Dest array ... template void Copy( T &source[], // Source Buffer ... T &dest[], // Dest Buffer ... bool cleanDest = true // Force Clen Dest Buffer ... ) { // if (cleanDest) { Clean(dest); } // int sourceCount = ArraySize(source); if (sourceCount <= 0) { return; } // for (int i = 0; i < sourceCount; i++) { // T iSource = source[i]; // AddRef( iSource, dest); } } // // Copy Items from a Buffer ... template int Copy( int start, // Start int count, // Number of Items for read T &source[], // Source Buffer T &dest[], // Dest Buffer bool forceClean = true, // Force To Clean buffer bool forceStart = true // Force To Clean buffer ) { // int result = 0; // if (forceClean) { Clean(dest); } // if (start < 0 && forceStart) { start = 0; } // if (start >= ArraySize(source)) { start = ArraySize(source) - 1; } // if (count == 0) { count = ArraySize(source) - 1 - start; } // if (start + count > ArraySize(source)) { return result; } // int beforeSize = ArraySize(dest); // bool asSeriesDest = ArrayGetAsSeries(dest); bool asSeriesSource = ArrayGetAsSeries(source); // ArraySetAsSeries(dest, true); ArraySetAsSeries(source, true); // ArrayCopy( dest, source, 0, start, count // ); // int afterSize = ArraySize(dest); // result = afterSize - beforeSize; // ArraySetAsSeries(dest, asSeriesDest); ArraySetAsSeries(source, asSeriesSource); // return result; } // // Copy Items from a Buffer ... template int CopyRef( int start, // Start int count, // Number of Items for read T &source[], // Source Buffer T &dest[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // int result = 0; // if (forceClean) { Clean(dest); } // if (start < 0) { start = 0; } // if (start >= ArraySize(source)) { start = ArraySize(source) - 1; } // int beforeSize = ArraySize(dest); // bool asSeriesDest = ArrayGetAsSeries(dest); bool asSeriesSource = ArrayGetAsSeries(source); // ArraySetAsSeries(dest, true); ArraySetAsSeries(source, true); // for (int i = start; i < start + count; i++) { // AddRef( source[i], dest // ); } // int afterSize = ArraySize(dest); // result = afterSize - beforeSize; // ArraySetAsSeries(dest, asSeriesDest); ArraySetAsSeries(source, asSeriesSource); // return result; } // // Retrive Last Item of Specified Buffer ... template bool GetLastItem( T &item, // Holds Result T &buffer[] // Specified Buffer ) { // bool result = false; // int bufferSize = ArraySize(buffer); if (bufferSize <= 0) { return result; } // item = buffer[bufferSize - 1]; // result = true; return result; } // // Remove Last Item of Specified Buffer ... template bool RemoveLastItem( T &buffer[] // Specified Buffer ) { // bool result = false; // int count = ArraySize(buffer); result = IsValidSize(count); if (!result) { return result; } // ArrayRemove( buffer, count - 1, 1 // ); // return result; } template void CleanupArray( T &buffer[], // Buffer to Cleanup ... int maxAllowed = 0 // Max Allowed Number of items ... ) { // if (maxAllowed <= 0) { return; } // int count = ArraySize(buffer); if (!IsValidSize(count) || count <= maxAllowed) { return; } // int mustRemove = count - maxAllowed; if (!IsValidSize(mustRemove)) { return; } // ArrayRemove( buffer, 0, mustRemove // ); } template void CleanupArray( int &removedIndexes[], T &buffer[] // Buffer to Cleanup ... ) { // bool isValid = HasChild(buffer) && HasChild(removedIndexes); if (!isValid) { return; } // for (int i = 0; i < ArraySize(removedIndexes); i++) { // int idx = removedIndexes[i]; if (IsValidIndex(idx) && ArraySize(buffer) > idx) { // ArrayRemove( buffer, idx, 1 // ); } } // Clean(removedIndexes); } // // Search Array For Specific Item ... template int FindIndex( T item, // What is Search ... T &buffer[] // Search in ... ) { // int result = -1; // int count = ArraySize(buffer); if (count <= 0) { return result; } // for (int i = 0; i < count; i++) { // T iT = buffer[i]; // if (iT == item) { // result = i; break; } } // return result; } template int FindXIndex( T item, // What is Search ... T &buffer[] // Search in ... ) { return FindIndex(item, buffer); } // // Find Specific Item Index inside a Collection ... template int FindIndex( T &item, // Item to Find const T &items[] // Items for Search ) { // int result = -1; // // Check Item Validation ... if (!item.IsValid()) { return result; } // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // for (int i = 0; i < itemsCount; i++) { // T iItem = items[i]; // // Validate Item ... if (!iItem.IsValid()) { continue; } // bool isSame = item.IsSameAs(iItem); if (isSame && result <= -1) { // result = i; break; } } // return result; } template int FindXIndex( T &item, // Item to Find const T &items[] // Items for Search ) { return FindIndex(item, items); } // // Check an Array Contains Specified Value ... template bool Contains( T item, // What is Search ... T &buffer[] // Search in ... ) { // bool result = false; // int idx = FindIndex( item, buffer); result = idx > -1; // return result; } // // Calculate a Buffer's Sum ... template double GetSum( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // double result = 0; // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Calculate Summary ... for (int i = 0; i < tmpCount; i++) { result += buffer[i]; } // return result; } // // Calculate a Buffer's Average ... template double GetAverage( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // double result = 0; // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Calculate Summary ... for (int i = 0; i < tmpCount; i++) { result += buffer[i]; } // // Calculate Average ... result = result / tmpCount; // return result; } // // Get Max of Specific Loopback of a Buffer ... template T GetMax( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // T result = 0; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // result = // result == 0 || result < iValue // ? iValue // : result // ; } // return result; } template T GetMaxWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { // T result = 0; index = -1; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // bool isNew = result == 0; bool canSet = isNew || (!isNew && result < iValue); if (canSet) { // index = i; result = iValue; } } // return result; } template T GetSpecifiedMax( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { return GetMax( buffer, start, count // ); } template T GetSpecifiedMaxWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { return GetMaxWidthIndex( buffer, index, start, count // ); } // // Get Min of Specific Loopback of a Buffer ... template T GetMin( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // T result = 0; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // result = // result == 0 || result > iValue // ? iValue // : result // ; } // return result; } template T GetMinWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { // T result = 0; index = -1; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // bool isNew = result == 0; bool canSet = isNew || (!isNew && result > iValue); if (canSet) { // index = i; result = iValue; } } // return result; } template T GetSpecifiedMin( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { return GetMin( buffer, start, count // ); } template T GetSpecifiedMinWidthIndex( T &buffer[], // the Buffer which required to search int &index, // Item Index ... int start = 0, // Start Index int count = 0 // Count for Search ) { return GetMinWidthIndex( buffer, index, start, count // ); } // // Find a Value less than Specified ... template T FindLesserThan( T value, // Specified Value ... const T &source[], // Source ... bool isDescend = false // Find Biggest Lesser Value ... ) { // T result = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source) // ); // ArrayCopy( tmp, source // ); // // Sort Temp Buffer ... ArraySort(tmp); if (isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue < value) { // result = iValue; break; } } // return result; } template T FindLesserThanByIndex( T value, // Specified Value ... int &index, // Item Index ... const T &source[], // Source ... bool isDescend = false // Find Biggest Lesser Value ... ) { // T result = -1; index = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source) // ); // ArrayCopy( tmp, source // ); // // Sort Temp Buffer ... ArraySort(tmp); if (isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue < value) { // index = i; result = iValue; break; } } // return result; } // // Find a Value less than Specified ... template T FindBiggerThan( T value, // Specified Value ... const T &source[], // Source ... bool isDescend = false // Find Smallest Bigger Value ... ) { // T result = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source) // ); // ArrayCopy( tmp, source // ); // // Sort Temp Buffer ... ArraySort(tmp); if (!isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue > value) { // result = iValue; break; } } // return result; } template T FindBiggerThanByIndex( T value, // Specified Value ... int &index, // Item Index ... const T &source[], // Source ... bool isDescend = false // Find Smallest Bigger Value ... ) { // T result = -1; index = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source) // ); // ArrayCopy( tmp, source // ); // // Sort Temp Buffer ... ArraySort(tmp); if (!isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue > value) { // index = i; result = iValue; break; } } // return result; } // // Find Same Values in Array ... template void FindSames( T &result[], // Holds Result ... T &source[], // Source ... int verifications = 3 // Number of Consequence Repeat ... ) { // Clean(result); // // TenkanSen Flats ... int sourceCount = ArraySize(source); if (sourceCount > verifications) { // T mLast = 0; int mVerified = 0; for (int i = 0; i < sourceCount; i++) { // T iVal = source[i]; if (mLast == 0) { mLast = iVal; } else if (mLast == iVal) { mVerified++; } else { mLast = iVal; mVerified = 0; } // if (iVal == mLast && mVerified >= verifications) { // Add( iVal, result); // mLast = 0; mVerified = 0; } } } } // // Add an Item to a Buffer if not Exists ... void AddIfNotExists( double value, double &values[], double smoothingPoint = 3 // ) { // double smoothingValue = smoothingPoint * GetPoints(_Symbol); // int valuesCount = ArraySize(values); if (valuesCount <= 0) { // Add(value, values); } else { // bool isExists = false; for (int i = 0; i < valuesCount; i++) { // double iVal = values[i]; // double diff = MathAbs(iVal - value); // if (iVal == value || diff < smoothingValue) { // isExists = true; break; } } // if (!isExists) { // Add(value, values); } } } // // Add a Buffers Child to another Buffer // if it's not Contains them ... void AddsIfNotExists( double &source[], double &dest[], double smoothingPoint = 3 // ) { // double smoothingValue = smoothingPoint * GetPoints(_Symbol); // int sourceCount = ArraySize(source); if (sourceCount <= 0) { return; } // for (int i = 0; i < sourceCount; i++) { // double iSource = source[i]; // AddIfNotExists( iSource, dest, smoothingPoint); } } // // END Collections ... // // // START Buffers ... // bool IsSame( double current, double previous, double tolerance = 2 // ) { // bool result = NotEmptyZero(current) && NotEmptyZero(previous) && current <= previous + tolerance && current >= previous + tolerance; // return result; } bool IsOver( double current, double previous, double tolerance = 2 // ) { // bool result = NotEmptyZero(current) && NotEmptyZero(previous) && current >= previous + tolerance; // return result; } bool IsUnder( double current, double previous, double tolerance = 2 // ) { // bool result = NotEmptyZero(current) && NotEmptyZero(previous) && current <= previous - tolerance; // return result; } // template bool IsSame( T &buffer[], // Search Buffer int count = 5, // Number of Searchs int start = 0 // Start ... ) { // bool result = false; // int bufferSize = ArraySize(buffer); result = bufferSize > 0; if (!result) { return result; } // // Validate Count ... result = start + count < bufferSize; if (!result) { return result; } // T iTem = buffer[start]; for (int i = start; i < start + count; i++) { // if (iTem != buffer[i]) { result = false; break; } // if (!result) { result = true; } } // return result; } // // Check first Cross Over second at index ... bool IsCrossedOver( const double &first[], // the buffer which check crossing over second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] > second[index] && !(first[index + 1] > second[index + 1]); // return result; } // // Check first is Over second at index ... bool IsOver( const double &first[], // the buffer which check over second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] > second[index] && first[index + 1] > second[index + 1]; // return result; } // // Check first Cross Under second at index ... bool IsCrossedUnder( const double &first[], // the buffer which check crossing under second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] < second[index] && !(first[index + 1] < second[index + 1]); // return result; } // // Check first is Under second at index ... bool IsUnder( const double &first[], // the buffer which check under second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] < second[index] && first[index + 1] < second[index + 1]; // return result; } // // Check if a Value Increasing in Loopback ... bool IsIncreasing( const double &buffer[], // the Buffer which required to search int from = -1, // Last Time Index int to = -1 // Fisrs Tima Index ) { // bool result = false; // if (from == -1) { from = ArraySize(buffer) - 1; } // if (to == -1) { to = 0; } // // Validate Args ... if ( from <= to || ArraySize(buffer) < from + 1) { return result; } // // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; result = toValue >= fromValue; for (int i = to + 1; i <= from - 1; i++) { // double iValue = buffer[i]; bool isPassed = toValue >= iValue; // bool isIIncreasing = IsIncreasing( buffer, from, i // ); // // Check Result ... result = result && isPassed && isIIncreasing; if (!result) { break; } } // return result; } // // Check if a Value Decreasing in Loopback ... bool IsDecreasing( const double &buffer[], // the Buffer which required to search int from = -1, // Last Time Index int to = -1 // Fisrs Tima Index ) { // bool result = false; // if (from == -1) { from = ArraySize(buffer) - 1; } // if (to == -1) { to = 0; } // // Validate Args ... if ( from <= to || ArraySize(buffer) < from + 1) { return result; } // // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; result = toValue <= fromValue; for (int i = to + 1; i <= from - 1; i++) { // double iValue = buffer[i]; bool isPassed = toValue <= iValue; // bool isIDecreasing = IsDecreasing( buffer, from, i // ); // // Check Result ... result = result && isPassed && isIDecreasing; if (!result) { break; } } // return result; } // bool IsTrendingUp( const double &buffer1[], // First Buffer const double &buffer2[] // Seccend Buffer ) { // bool result = false; // int buffer1Count = ArraySize(buffer1); int buffer2Count = ArraySize(buffer2); if (buffer1Count <= 0 || buffer2Count <= 0) { return result; } // int count = MathMin(buffer1Count, buffer2Count); if (count <= 1) { return result; } // int upCounts = 0; int downCounts = 0; double value = MathAbs(buffer1[0] - buffer2[0]); for (int i = 1; i < count; i++) { // double iValue = MathAbs(buffer1[i] - buffer2[i]); // if (value > iValue) { upCounts++; } // if (value < iValue) { downCounts++; } } // result = upCounts > 1 && upCounts > downCounts; // return result; } // bool IsTrendingDown( const double &buffer1[], // First Buffer const double &buffer2[] // Seccend Buffer ) { // bool result = false; // int buffer1Count = ArraySize(buffer1); int buffer2Count = ArraySize(buffer2); if (buffer1Count <= 0 || buffer2Count <= 0) { return result; } // int count = MathMin(buffer1Count, buffer2Count); if (count <= 1) { return result; } // int upCounts = 0; int downCounts = 0; double value = MathAbs(buffer1[0] - buffer2[0]); for (int i = 1; i < count; i++) { // double iValue = MathAbs(buffer1[i] - buffer2[i]); // if (value > iValue) { upCounts++; } // if (value < iValue) { downCounts++; } } // result = downCounts > 1 && downCounts > upCounts; // return result; } // // Calculate Slope of Specified Buffer at Specified Index ... double GetSlope( const double &buffer[], // Buffer int from, // In Past Index ... int to // In Past Index ... ) { // double result = 0; // if (from > ArraySize(buffer) || to > ArraySize(buffer)) { return result; } // double toValue = buffer[to]; double fromValue = buffer[from]; double deltaValue = toValue - fromValue; double deltaTime = from - to; // result = deltaValue / deltaTime; // return result; } // // END Buffers ... // // // START Time ... // // // Converts Time to Seconds ... ulong TimeToSeconds( datetime time // Specify time to Convert ... ) { // ulong result = (ulong)time; // return result; } ulong TimeToSeconds( MqlDateTime &time // Specify time to Convert ... ) { // datetime dTime = StructToTime(time); // ulong result = TimeToSeconds(dTime); // return result; } // // Converts Seconds To Time ... datetime SecondsToTime( ulong seconds // Specify Seconds to Convert ... ) { // datetime result = (datetime)seconds; // return result; } MqlDateTime SecondsToStruct( ulong seconds // Specify Seconds to Convert ... ) { // datetime dTime = SecondsToTime(seconds); // MqlDateTime result = {}; TimeToStruct( dTime, result); // return result; } // // Converts Time to MilliSeconds ... ulong TimeToMilliSeconds( datetime time // Specify time to Convert ... ) { // ulong result = TimeToSeconds(time) * 1000; // return result; } ulong TimeToMilliSeconds( MqlDateTime &time // Specify time to Convert ... ) { // datetime dTime = StructToTime(time); // ulong result = TimeToMilliSeconds(dTime); // return result; } // // Converts MillisSeconds to Time ... datetime MilliSecondsToTiem( ulong milliSeconds // Specify MilliSeconds to Convert ... ) { // ulong seconds = milliSeconds / 1000; // datetime result = SecondsToTime(seconds); // return result; } MqlDateTime MilliSecondsToStruct( ulong milliSeconds // Specify MilliSeconds to Convert ... ) { // datetime dTime = MilliSecondsToTiem(milliSeconds); // MqlDateTime result = {}; TimeToStruct( dTime, result); // return result; } // // Converts Hours to Seconds ... int HoursToSeconds(int value) { // int result = 0; // if (value < 0) { value = 0; } // if (value == 0) { return result; } // result = value * 60 * 60; // return result; } // // Retrieve DateTime Structure ... MqlDateTime GetCurrentTime() { // MqlDateTime result = {}; // datetime cTime = TimeCurrent(); TimeToStruct(cTime, result); // return result; } // // Retrieve Current Time as Seconds ... ulong GetCurrentTimeAsSeconds() { // datetime time = TimeCurrent(); // ulong result = TimeToSeconds(time); // return result; } // // Retrieve Current Time as MilliSeconds ... ulong GetCurrentTimeAsMilliSeconds() { // datetime time = TimeCurrent(); // ulong result = TimeToMilliSeconds(time); // return result; } // int GetLocalOffset() { // MqlDateTime cTimeStruct; datetime cTime = TimeCurrent(cTimeStruct); // MqlDateTime cLTimeStruct; datetime cLTime = TimeLocal(cLTimeStruct); // cTimeStruct.sec = 0; cTime = StructToTime(cTimeStruct); // cLTimeStruct.sec = 0; cLTime = StructToTime(cLTimeStruct); // int result = ((int)cLTime - (int)cTime); // return result; } // int GetUTCRequiredTimeOffset() { // int utcOffset = TimeGMTOffset(); int localOffset = GetLocalOffset(); // int result = utcOffset + localOffset; // return result; } // datetime GetUTCTime( datetime time = NULL, bool applyTradeServerTime = false // ) { // datetime result = NULL; // NormalizeTime(time); // datetime cTime = TimeCurrent(); datetime cTimeLocal = TimeLocal(); // int cLocalOffset = ((int)cTimeLocal - (int)cTime); int gmtOffset = TimeGMTOffset(); int offsetDelte = gmtOffset + cLocalOffset; int requiredUTCOffset = GetUTCRequiredTimeOffset(); if (requiredUTCOffset > 0) { requiredUTCOffset = -1 * requiredUTCOffset; } // int timeSeconds = (int)time; int resultSeconds = timeSeconds + requiredUTCOffset; // result = (datetime)(resultSeconds); // return result; } // // Retrieve only Hour and Minute as String ... string GetTimeString( datetime time = NULL // ) { // NormalizeTime(time); // string result = NULL; // MqlDateTime tStruct; bool isStructed = TimeToStruct(time, tStruct); if (!isStructed) { return result; } // string hour = ToXString(tStruct.hour); hour = StringLen(hour) == 1 ? "0" + hour : hour; // string minute = ToXString(tStruct.min); minute = StringLen(minute) == 1 ? "0" + minute : minute; // result = hour + ":" + minute; // return result; } // // Converts a Date time to File Format ... string ToFormatString( datetime mTime, string separator = "_" // ) { // string result = NULL; // if (!IsValid(mTime)) { return result; } // MqlDateTime timeStruct; bool isConverts = TimeToStruct( mTime, timeStruct // ); if (!isConverts) { return result; } // string year = ToXString(timeStruct.year); string month = ToXString(timeStruct.mon); string day = ToXString(timeStruct.day); string hour = ToXString(timeStruct.hour); string minute = ToXString(timeStruct.min); string second = ToXString(timeStruct.sec); // result = // // Year ... year + separator + // // Month ... (StringLen(month) == 1 ? "0" + month : month) + separator + // // Day ... (StringLen(day) == 1 ? "0" + day : day) + separator + // // Hour ... (StringLen(hour) == 1 ? "0" + hour : hour) + separator + // // Minute ... (StringLen(minute) == 1 ? "0" + minute : minute) + separator + // // Seconds ... (StringLen(second) == 1 ? "0" + second : second) + separator + // "" // ; // return result; } /** * Converts an String Represetation of Time (00:00) to Date Time .. * * @param value: String ... * * @return ( datetime ) */ datetime ParseDateTimeFromTimeString(string value) { // datetime result = NULL; // if (!IsValid(value)) { return result; } // // Check Signalling Time ... MqlDateTime cTime; bool isTimeRecieved = TimeCurrent(cTime); if (!isTimeRecieved) { return result; } // // Split ... string parts[]; int partsCount = SplitContent( parts, value, ":" // ); if (!IsValidSize(partsCount)) { return result; } // int hour = 0; int minute = 0; if (partsCount >= 1) { hour = (int)(parts[0]); } if (partsCount >= 2) { minute = (int)(parts[1]); } // cTime.day_of_week = 0; cTime.day_of_year = 0; // cTime.hour = hour; cTime.min = minute; // result = StructToTime(cTime); // return result; } // // Check Specific Time in Range of another Time ... bool IsTimeInRange( datetime currentTime = NULL, datetime startTime = NULL, datetime stopTime = NULL // ) { // bool result = false; // // Normallize Current Time ... currentTime = NormalizeTime(currentTime); // result = !IsValid(startTime) && !IsValid(stopTime); if (result) { return result; } // result = IsValid(startTime) && IsValid(stopTime); if (!result) { // result = IsValid(startTime) && currentTime >= startTime; // return result; } // result = currentTime >= startTime && currentTime < stopTime; // return result; } bool IsTimeInRange( datetime currentTime, string startTime, string endTime // ) { // bool result = false; // result = IsValid(startTime) && IsValid(endTime); if (!result) { // // Here Since there isnot provide any // data source we pass result as true ... result = true; return result; } // // Converts String Representation to Time ... datetime st = ParseDateTimeFromTimeString(startTime); datetime et = ParseDateTimeFromTimeString(endTime); // result = IsTimeInRange( currentTime, st, et // ); // return result; } // // END Time ... // // // START Price ... // // // Get 1 Pip in Price Value ... double GetPipPrice( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double symbolPoint = GetPoints(mSymbol); int symbolDigits = GetDigits(mSymbol); // double result = symbolPoint; if (symbolDigits == 3 || symbolDigits == 5) { result *= 10; } // return result; } /** * Calculate Applied Price ... * * @param mType: ENUM_X_PRICE member, Price Type ... * @param mOpen: double collection, Open Prices ... * @param mHigh: double collection, High Prices ... * @param mLow: double collection, Low Prices ... * @param mClose: double collection, Close Prices ... * @param barIndex: int, Index ... * * @return ( double ) */ double GetAppliedPrice( ENUM_X_PRICE mType, // Type of Price Selection const double &mOpen[], // Open Prices const double &mHigh[], // High Preices const double &mLow[], // Low Prices const double &mClose[], // Close Prices int barIndex // Bar Index ) { // double result = 0; // switch (mType) { // case X_PRICE_NONE: result = 0; break; // case X_PRICE_HIGH: result = mHigh[barIndex]; break; // case X_PRICE_OPEN: result = mOpen[barIndex]; break; // case X_PRICE_CLOSE: result = mClose[barIndex]; break; // case X_PRICE_LOW: result = mLow[barIndex]; break; // case X_PRICE_UP: result = MathMax(mOpen[barIndex], mClose[barIndex]); break; // case X_PRICE_DOWN: result = MathMin(mOpen[barIndex], mClose[barIndex]); break; // case X_PRICE_MEDIAN: result = ((mHigh[barIndex] + mLow[barIndex]) / 2.0); break; // case X_PRICE_BODY_MEDIAN: result = ((mOpen[barIndex] + mClose[barIndex]) / 2.0); break; // case X_PRICE_TYPICAL: result = ((mHigh[barIndex] + mLow[barIndex] + mClose[barIndex]) / 3.0); break; // case X_PRICE_WEIGHTED: result = (((mHigh[barIndex] + mLow[barIndex] + mClose[barIndex] + mClose[barIndex]) / 4.0)); break; } // return result; } /** * Calculate Applied Price ... * * @param mType: ENUM_X_PRICE member, Price Type ... * @param mOpen: double, Open Price ... * @param mHigh: double, High Price ... * @param mLow: double, Low Price ... * @param mClose: double, Close Price ... * @param barIndex: int, Index ... * * @return ( double ) */ double GetAppliedPrice( ENUM_X_PRICE mType, // Type of Price Selection double mOpen, // Open Prices double mHigh, // High Preices double mLow, // Low Prices double mClose // Close Prices ) { // double result = 0; // switch (mType) { // case X_PRICE_NONE: result = 0; break; // case X_PRICE_HIGH: result = mHigh; break; // case X_PRICE_OPEN: result = mOpen; break; // case X_PRICE_CLOSE: result = mClose; break; // case X_PRICE_LOW: result = mLow; break; // case X_PRICE_UP: result = MathMax(mOpen, mClose); break; // case X_PRICE_DOWN: result = MathMin(mOpen, mClose); break; // case X_PRICE_MEDIAN: result = ((mHigh + mLow) / 2.0); break; // case X_PRICE_BODY_MEDIAN: result = ((mOpen + mClose) / 2.0); break; // case X_PRICE_TYPICAL: result = ((mHigh + mLow + mClose) / 3.0); break; // case X_PRICE_WEIGHTED: result = (((mHigh + mLow + mClose + mClose) / 4.0)); break; } // return result; } /** * Calculate Applied Price ... * * @param mSymbol: string, Specified Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ... * @param barIndex: int, Specified Bar Index ... * @param mType: ENUM_X_PRICE member, Specified Price Type ... * * @return ( double ) */ double GetAppliedPrice( string mSymbol = NULL, // Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Period int barIndex = 0, // Bar Index ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); barIndex = NormalizeInt(barIndex, 0); // bool has = IsValid(mType); if (!has) { return result; } // double open = iOpen( mSymbol, mPeriod, barIndex // ); // double high = iHigh( mSymbol, mPeriod, barIndex // ); // double low = iLow( mSymbol, mPeriod, barIndex // ); // double close = iClose( mSymbol, mPeriod, barIndex // ); // // Retrieve Applied Price ... result = GetAppliedPrice( mType, open, high, low, close // ); // return result; } /** * Calculate Applied Price ... * * @param mSymbol: string, Specified Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ... * @param time: int, Specified Bar Time ... * @param mType: ENUM_X_PRICE member, Specified Price Type ... * * @return ( double ) */ double GetAppliedPrice( string mSymbol = NULL, // Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Period datetime mTime = NULL, // Bar Time ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection ) { // double result = 0; // mTime = NormalizeTime(mTime); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // bool has = IsValid(mType); if (!has) { return result; } // int barIndex = GetBarIndex( mSymbol, mPeriod, mTime // ); has = IsValidIndex(barIndex); if (!has) { return result; } // // Retrieve Applied Price ... result = GetAppliedPrice( mSymbol, mPeriod, barIndex, mType // ); // return result; } /** * Calculate Price Boundary ... * * @param upper: double collection reference, Upper Boundary ... * @param lower: double collection reference, Lower Boundary ... * @param mSymbol: string, Specified Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ... * @param mMode: ENUM_X_BOUNDARY_PRICE member, Specified Boundary Mode ... * @param mLength: int, Loopback Length of Bondary ... * @param barIndex: int, Specified Bar Index ... * @return ( int ) */ int GetPriceBoundary( double &upper[], // Upper Boundary double &lower[], // Lower Boundary string mSymbol = NULL, // Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Period ENUM_X_BOUNDARY_PRICE mMode = NULL, // Boundary Mode int mLength = 1, // Length int barIndex = 0 // Bar Index ) { // int result = 0; // Clean(upper); Clean(lower); // // Normalize Args ... mMode = NormalizeBoundary(mMode); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); mLength = NormalizeInt(mLength, 1); barIndex = NormalizeInt(barIndex, 0); // // Prepare Boundary Price Types ... ENUM_X_PRICE upperType = mMode == X_BOUNDARY_PRICE_UP_DOWN ? X_PRICE_UP : mMode == X_BOUNDARY_PRICE_HIGH_LOW ? X_PRICE_HIGH : X_PRICE_NONE; ENUM_X_PRICE lowerType = mMode == X_BOUNDARY_PRICE_UP_DOWN ? X_PRICE_DOWN : mMode == X_BOUNDARY_PRICE_HIGH_LOW ? X_PRICE_LOW : X_PRICE_NONE; // // Check Boundary Type Validation ... bool isValid = IsValid(lowerType) && IsValid(upperType); if (!isValid) { return result; } // // Loop through Loopbacks ... int start = barIndex + mLength; int end = barIndex; for (int i = start; i >= end; i--) { // double iUpper = GetAppliedPrice( mSymbol, mPeriod, i, upperType // ); double iLower = GetAppliedPrice( mSymbol, mPeriod, i, lowerType // ); // Add( iUpper, upper // ); // Add( iLower, lower // ); } // result = ArraySize(upper); // return result; } /** * Get Applied Price Buffer ... * * @param mType: ENUM_X_PRICE, Specified Price Type ... * @param dest: double, Holds Destination Prices ... * @param mOpen: double collection, Open Prices ... * @param mHigh: double collection, High Prices ... * @param mLow: double collection, Low Prices ... * @param mClose: double collection, Close Prices ... * * @return ( int ) */ int GetAppliedPrice( ENUM_X_PRICE mType, double &dest[], const double &mOpen[], // Open Prices const double &mHigh[], // High Preices const double &mLow[], // Low Prices const double &mClose[] // Close Prices ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Check ArraySizes ... int count = ArraySize(mOpen); count = MathMin(count, ArraySize(mHigh)); count = MathMin(count, ArraySize(mClose)); count = MathMin(count, ArraySize(mLow)); // // Validate ... if (!IsValidSize(count)) { return result; } // // Loopback ... for (int i = 0; i < count; i++) { // double iPrice = GetAppliedPrice( mType, mOpen[i], mHigh[i], mLow[i], mClose[i] // ); // Add( iPrice, dest // ); } // result = ArraySize(dest); // return result; } // // END Price ... // // // START Bar ... // /** * Retrieve Specific Bar's Time ... * * @param mSymbol: string, Provided Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Provided Period ... * @param barIndex: int, Provided Bar Index ... * * @return ( datetime ) */ datetime GetBarTime( string mSymbol = NULL, // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame int barIndex = 0 // Specify Bar Index ) { // // Validate and Normalize Args ... // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // // Retrieve Bar Time ... datetime result = iTime( mSymbol, mPeriod, barIndex // ); // return result; } /** * Retrieve Specific Bar's Index ... * * @param mSymbol: string, Provided Symbol ... * @param mPeriod: ENUM_TIMEFRAMES member, Provided Period ... * @param barTime: datetime, Provided Bar Time ... * * @return ( datetime ) */ int GetBarIndex( string mSymbol = NULL, // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame datetime barTime = NULL // Specify Bar Time ) { // // Validate and Normalize Args ... // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // // Retrieve Bar Time ... int result = iBarShift( mSymbol, mPeriod, barTime // ); // return result; } // // END Bar ... // // // START Chart Info ... // ENUM_CHART_MODE GetChartMode(long chartId = 0) { return (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); } color GetChartUpColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); } color GetChartDownColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); } color GetChartBullishColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); } color GetChartBearishColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); } color GetChartLineColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); } color GetChartForeGroundColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); } color GetChartBackGroundColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); } color GetChartGridColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_GRID); } color GetChartBidLineColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_BID); } color GetChartAskLineColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_ASK); } color GetChartStopColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); } color GetChartVolumesColor(long chartId = 0) { return (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); } bool GetChartShowBidLine(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); } bool GetChartShowAskLine(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); } bool GetChartShowGrid(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); } bool GetChartShowVolumes(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); } bool GetChartShowTradeLevels(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); } bool GetChartAutoScroll(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); } bool GetChartQuickNavigation(long chartId = 0) { return (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); } // // // bool SetChartMode( ENUM_CHART_MODE value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_MODE, value); } bool SetChartShowBidLine( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_SHOW_BID_LINE, value); } bool SetChartShowAskLine( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, value); } bool SetChartShowGrid( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_SHOW_GRID, value); } bool SetChartShowVolumes( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_SHOW_VOLUMES, value); } bool SetChartShowTradeLevels( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, value); } bool SetChartAutoScroll( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_AUTOSCROLL, value); } bool SetChartQuickNavigation( bool value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, value); } bool SetChartForeGroundColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, value); } bool SetChartBackGroundColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, value); } bool SetChartUpColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_CHART_UP, value); } bool SetChartDownColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, value); } bool SetChartBullishColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, value); } bool SetChartBearishColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, value); } bool SetChartGridColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_GRID, value); } bool SetChartBidLineColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_BID, value); } bool SetChartAskLineColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_ASK, value); } bool SetChartStopColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, value); } bool SetChartLineColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, value); } bool SetChartVolumesColor( color value, long chartId = 0 // ) { return ChartSetInteger(chartId, CHART_COLOR_VOLUME, value); } // // END Chart Info ... // // // START ATR ... // /** * Calculate True Range of Specified Bar ... * * @param _symbol: string, Symbol ... * @param _period: ENUM_TIMEFRAMES, period ... * @param _barIndex: int, Specified Bar Index ... * @param ignorePC: bool, Ignore Previous Bar ... * * @return ( double ) */ double GetTrueRange( string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL, int _barIndex = 0, bool ignorePC = false // Ignore Previous Close ... ) { // double result = EMPTY_VALUE; // // Normalize ... _symbol = NormalizeSymbol(_symbol); _period = NormalizePeriod(_period); _barIndex = NormalizeInt(_barIndex, 0); // double _low = iLow(_symbol, _period, _barIndex); double _high = iHigh(_symbol, _period, _barIndex); double _pLow = iLow(_symbol, _period, _barIndex + 1); double _pHigh = iHigh(_symbol, _period, _barIndex + 1); double _pClose = iClose(_symbol, _period, _barIndex + 1); // double hlDiff = _high - _low; // if (!ignorePC) { // double hpcDiff = MathAbs(_high - _pClose); double lpcDiff = MathAbs(_high - _pClose); // result = MathMax(hlDiff, hpcDiff); result = MathMax(result, lpcDiff); } else { result = hlDiff; } // return result; } /** * Calculate ATR ... * * @param _symbol: string, Symbol ... * @param _period: ENUM_TIMEFRAMES, period ... * @param _barIndex: int, Specified Bar Index ... * @param _length: int ATR Period ... * * @return ( double ) */ double GetAverageTrueRange( string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL, int _barIndex = 0, int _length = 14 // ) { // double result = EMPTY_VALUE; // // Normalize ... _symbol = NormalizeSymbol(_symbol); _period = NormalizePeriod(_period); _length = NormalizeInt(_length, 2); _barIndex = NormalizeInt(_barIndex, 0); // // Collect True Ranges ... double itr; double _trs[]; bool has = false; int start = _barIndex; int end = start + _length; for (int i = start; i < end; i++) { // itr = GetTrueRange( _symbol, _period, _barIndex, i == end - 1 // Ignore PC ... ); has = NotEmptyZero(itr); if (has) { // Add( itr, _trs // ); } } // int count = ArraySize(_trs); has = HasChild(_trs); if (!has) { return result; } // result = GetAverage(_trs); // // Cleanup ... XClean(_trs); // return result; } // // END ÙŽATR ... // // // START Linear Regression ... // /** * Calculate Slope and Intercept for Linear Regression Predictions ... * * @param _slope: double, refrence to Hold Calculated Slope ... * @param _intercept: double, reference to Hold Calculated Intercept ... * @param xData: double, reference Collection to Provides X-Axis Data for Calculations ... * @param yData: double, reference Collection to Provides Y-Axis Data for Calculations ... * * @return ( int ) */ int CalculateSlopeAndIntercept( double &_slope, double &_intercept, double &xData[], double &yData[] // ) { // int result = 0; // bool has = false; // _slope = 0; _intercept = 0; // if (!HasChild(xData) || !HasChild(yData)) { return result; } // double sumX = 0; double sumY = 0; double sumXY = 0; double sumX2 = 0; // double x = 0; double y = 0; int end = MathMin(ArraySize(xData), ArraySize(yData)); for (int i = 0; i < end; i++) { // double x = xData[i]; double y = yData[i]; // sumX += x; sumY += y; sumXY += x * y; sumX2 += x * x; } // int n = end; double _dividedBy = (n * sumX2 - sumX * sumX); // if (_dividedBy <= 0 || n <= 0) // { // // // _slope = 0; // _intercept = 0; // // // result = 0; // } else { // // // _slope = (n * sumXY - sumX * sumY) / _dividedBy; // _intercept = (sumY - _slope * sumX) / n; // // // result = n; // } // _slope = (n * sumXY - sumX * sumY) / _dividedBy; _intercept = (sumY - _slope * sumX) / n; // result = n; // return result; } /** * Predict Value for Specified X ... * * @param _sllope: double, Provided Slope ... * @param _intercept: double, Provided Intercept ... * @param _forX: double, Specified XValue ... * * @return ( double ) */ double PredictValue( double _slope, double _intercept, double _forX // ) { // double result = 0; // // Validate ... if (!NotEmpty(_forX) || !NotEmpty(_slope) || !NotEmpty(_intercept)) { return result; } // result = (_intercept + (_slope * _forX)); // return result; } // // END Linear Regression ... // // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.common.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XCommonLib // Description: provide all commonly used functions ... // // // 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 "../Libraries/x-saherelm.common.extensions.lib.mq5" #include "../Libraries/x-saherelm.common.models.lib.mq5" #include "../Libraries/x-saherelm.x-ohcl.lib.mq5" // // Models ... // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.common.models.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XModelsLib // Description: provide all commonly used functions ... // // // 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 // #include "../Libraries/x-saherelm.common.extensions.lib.mq5" // // Use To Parse Symbols for // Ignore Brokers Additional Suffixes ... struct XSymbolParser { // string version; // Temp ... // // Symbol Parsing ... // // Forext ... // bool IsEURUSD(string symbol) { // string symbolIdentifiers[] = { "EUR", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsUSDJPY(string symbol) { // string symbolIdentifiers[] = { "USD", "JPY" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURJPY(string symbol) { // string symbolIdentifiers[] = { "EUR", "JPY" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsUSDCHF(string symbol) { // string symbolIdentifiers[] = { "USD", "CHF" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURCHF(string symbol) { // string symbolIdentifiers[] = { "EUR", "CHF" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsGBPUSD(string symbol) { // string symbolIdentifiers[] = { "GBP", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURGBP(string symbol) { // string symbolIdentifiers[] = { "EUR", "GBP" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsAUDUSD(string symbol) { // string symbolIdentifiers[] = { "AUD", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURAUD(string symbol) { // string symbolIdentifiers[] = { "EUR", "AUD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsUSDCAD(string symbol) { // string symbolIdentifiers[] = { "USD", "CAD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURCAD(string symbol) { // string symbolIdentifiers[] = { "EUR", "CAD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsNZDUSD(string symbol) { // string symbolIdentifiers[] = { "NZD", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsEURNZD(string symbol) { // string symbolIdentifiers[] = { "EUR", "NZD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // // Metals ... // bool IsXAUUSD(string symbol) { // string symbolIdentifiers[] = { "XAU", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // bool IsXAGUSD(string symbol) { // string symbolIdentifiers[] = { "XAG", "USD" // }; // bool result = Contains( symbolIdentifiers, symbol // ); // return result; } // // Indexes ... // bool IsDowJones(string symbol) { // bool result = Contains( "DowJones30", symbol // ); // return result; } // // Oil ... // bool IsBrent(string symbol) { // bool result = Contains( "BRENT", symbol // ); // return result; } // // Symbol Finder ... string GetEURUSDSymbol() { // string result = NULL; // string symbols[]; int symbolsCount = GetAllSymbols( symbols // ); if (!IsValidSize(symbolsCount)) { return result; } // for (int i = 0; i < symbolsCount; i++) { // string iSymbol = symbols[i]; if (IsEURUSD(iSymbol)) { // result = iSymbol; break; } } // return result; } }; ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.draw.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Draw Library // -------------------------------------- // Name: XDraw // Description: provides Draw abilities ... // // // 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 // // Global Definitions: Variables, Properties and etc ... // // Retrieve Chart Size in Pixel ... struct XSize { long width; long height; // int x; int y; int w; int h; // int wStep; int hStep; }; // // Define a Draw Specifications ... struct XDrawSpecifications { // // Props ... // bool draw; // Draw or Not ... // int width; // Draw Witdth ... color clr; // Draw Color ... ENUM_LINE_STYLE style; // Draw Style ... // bool back; // in the background bool fill; // fill object if supported bool selection; // highlight to move bool rayRight; // line's continuation to the right bool hidden; // hidden in the object list long zOrder; // priority for mouse click // string label; // Label ... color labelColor; // Label Color ... double labelAngel; // Label Angle ... string labelFont; // Label Font ... int labelFontSize; // Label Font Size ... ENUM_ANCHOR_POINT labelAnchor; // Label Anchor Point ... // // Constructor ... XDrawSpecifications() { Clean(); } // // Operator ... void operator=(const XDrawSpecifications &value) { // clr = value.clr; draw = value.draw; width = value.width; style = value.style; // back = value.back; hidden = value.hidden; zOrder = value.zOrder; rayRight = value.rayRight; selection = value.selection; // fill = value.fill; // label = value.label; labelColor = value.labelColor; labelAngel = value.labelAngel; labelFont = value.labelFont; labelFontSize = value.labelFontSize; labelAnchor = value.labelAnchor; } // // Functions ... // void Clean() { // draw = false; width = 1; clr = CLR_NONE; style = STYLE_SOLID; // back = false; hidden = false; rayRight = false; selection = false; fill = false; // zOrder = 0; // label = ""; labelColor = CLR_NONE; labelAngel = 0; labelFont = "Arial"; labelFontSize = 20; labelAnchor = ANCHOR_LEFT_UPPER; // ZeroMemory(this); } // void Label( string mLabel = "", // Label ... color mLabelColor = CLR_NONE, // Label Color ... string mLabelFont = "Arial", // Label Font ... int mLabelFontSize = 20, // Label Font Size ... ENUM_ANCHOR_POINT mLabelAnchor = ANCHOR_LEFT_UPPER, // Label Anchor Point ... double mLabelAngel = 0 // Label Angle ... ) { // label = mLabel; labelFont = mLabelFont; labelColor = mLabelColor; labelAngel = mLabelAngel; labelAnchor = mLabelAnchor; labelFontSize = mLabelFontSize; } }; // // Candle Draw Specifications ... struct XOHCLDrawSpecification { // // Props ... XDrawSpecifications openStyle; XDrawSpecifications highStyle; XDrawSpecifications closeStyle; XDrawSpecifications lowStyle; // // Constructors ... XOHCLDrawSpecification() { Clean(); } // // Operators ... void operator=(const XOHCLDrawSpecification &value) { // lowStyle = value.lowStyle; openStyle = value.openStyle; highStyle = value.highStyle; closeStyle = value.closeStyle; } // // Functions ... // void Clean() { // lowStyle.Clean(); openStyle.Clean(); highStyle.Clean(); closeStyle.Clean(); // ZeroMemory(this); } // void Default() { // // Open ... openStyle.width = 1; openStyle.draw = true; openStyle.clr = clrLime; openStyle.style = STYLE_SOLID; openStyle.Label( "O", openStyle.clr); // // High ... highStyle.width = 1; highStyle.draw = true; highStyle.clr = clrAqua; highStyle.style = STYLE_SOLID; highStyle.Label( "H", highStyle.clr); // // Close ... closeStyle.width = 1; closeStyle.draw = true; closeStyle.clr = clrRed; closeStyle.style = STYLE_SOLID; closeStyle.Label( "C", closeStyle.clr); // // Low ... lowStyle.width = 1; lowStyle.draw = true; lowStyle.clr = clrMagenta; lowStyle.style = STYLE_SOLID; lowStyle.Label( "L", lowStyle.clr); } // void Width(int value) { // lowStyle.width = value; openStyle.width = value; highStyle.width = value; closeStyle.width = value; } // void Style(ENUM_LINE_STYLE value) { // lowStyle.style = value; openStyle.style = value; highStyle.style = value; closeStyle.style = value; } // void Color(color value) { // lowStyle.clr = value; openStyle.clr = value; highStyle.clr = value; closeStyle.clr = value; } // void RayRight(bool value) { // lowStyle.rayRight = value; openStyle.rayRight = value; highStyle.rayRight = value; closeStyle.rayRight = value; } // void Draw(bool value) { // lowStyle.draw = value; openStyle.draw = value; highStyle.draw = value; closeStyle.draw = value; } // void Back(bool value) { // lowStyle.back = value; openStyle.back = value; highStyle.back = value; closeStyle.back = value; } // void Fill(bool value) { // lowStyle.fill = value; openStyle.fill = value; highStyle.fill = value; closeStyle.fill = value; } // void Label(string value) { // lowStyle.Label(value); openStyle.Label(value); highStyle.Label(value); closeStyle.Label(value); } // void SetLabelPrefix(string value) { // lowStyle.label = value + " " + lowStyle.label; openStyle.label = value + " " + openStyle.label; highStyle.label = value + " " + highStyle.label; closeStyle.label = value + " " + closeStyle.label; } }; // string drawPrefix = "X-OBJ"; // // Common Draw Functions ... // // remove drawn objects ... void RemoveDraws( string tag = NULL, long chartId = -1, int subWindow = -1 // ) { // // Normalize Args ... // if (tag == NULL) { tag = drawPrefix; } // if (chartId == -1) { chartId = 0; } // if (subWindow == -1) { subWindow = 0; } // for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) { // string on = ObjectName(chartId, iObj, subWindow); if (StringFind(on, tag) >= 0) { ObjectDelete(chartId, on); } } // // Redraw Chart ... ChartRedraw(); } // bool RemoveDraw( string name, long chartId = -1, int subWindow = -1 // ) { // bool result = false; // if (chartId == -1) { chartId = 0; } // if (subWindow == -1) { subWindow = 0; } // string objName = ""; for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) { // string on = ObjectName(chartId, iObj, subWindow); if (StringFind(on, name) >= 0) { // objName = on; break; } } // if (StringLen(objName) > 0) { result = ObjectDelete(chartId, objName); } // return result; } // // Deselect All Draws ... void DeselectAllDraws() { // int objs = ObjectsTotal(ChartID(), 0); for (int o = 0; o < objs; o++) { ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); } // ChartRedraw(); } // // Check Object Exists ... bool IsDrawExists( string name, long chartId = -1, int subWindow = -1 // ) { // bool result = false; // if (chartId == -1) { chartId = 0; } // if (subWindow == -1) { subWindow = 0; } // for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) { // string on = ObjectName(chartId, iObj, subWindow); result = StringFind(on, name) >= 0; if (result) { break; } } // return result; } // // Find Specific Object Name ... string FindObjectName( string suggest, long chartId = 0, int subWindow = 0 // ) { // string result = NULL; // int objectsCount = ObjectsTotal(chartId, subWindow); if (objectsCount <= 0) { return result; } // for (int i = objectsCount - 1; i >= 0; i--) { // string iObjectName = ObjectName(chartId, i, subWindow); bool isExists = StringFind(iObjectName, suggest) >= 0; if (isExists) { // result = iObjectName; break; } } // return result; } // // Regular Draws ... // // Arrow Functions ... // // Draw an Arrow Object on Chart ... bool DrawArrow( const long chartID = 0, // chart's ID const string name = "Arrow", // arrow name const int subWindow = 0, // subwindow index datetime time = 0, // anchor point time double price = 0, // anchor point price const uchar arrowCode = 252, // arrow code const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position const color clr = clrAqua, // arrow color const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style const int width = 3, // arrow size const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = false, // hidden in the object list const long zOrder = 0 // Order Object ... ) { // bool result = false; // // set anchor point coordinates if they are not set ... ChangeArrowEmptyPoint(time, price); // // reset the error value ... ResetLastError(); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create an arrow ... result = ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price); if (!result) { return result; } // // set the arrow code ... ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); // // set anchor type ... ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); // // set the arrow color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set the border line style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set the arrow's size ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the arrow by mouse // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is false by default, if you want making it possible to highlight and move the object // change it to true ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move the anchor point of Arrow ... bool MoveArrow( const long chartID = 0, // chart's ID const string name = "Arrow", // object name datetime time = 0, // anchor point time coordinate double price = 0 // anchor point price coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if point position is not set, move it to the current bar having Bid price ... if (!time) { time = TimeCurrent(); } // if (!price) { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); } // // move the anchor point ... result = ObjectMove(chartID, objName, 0, time, price); // return result; } // // Delete an arrow ... bool DeleteArrow( const long chartID = 0, // chart's ID const string name = "Arrow" // arrow name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete an arrow ... result = !ObjectDelete(chartID, objName); // return result; } // // Change the arrow code ... bool ArrowCodeChange( const long chartID = 0, // chart's ID const string name = "Arrow", // object name const uchar code = 252 // arrow code ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change the arrow code ... result = ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, code); // return result; } // // Change anchor type ... bool ArrowAnchorChange( const long chartID = 0, // chart's ID const string name = "Arrow", // object name const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change anchor type ... result = !ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); // return result; } // // Check anchor point values and set default values // for empty ones ... void ChangeArrowEmptyPoint( datetime &time, double &price // ) { // // if the point's time is not set, it will be on the current bar ... if (!time) { time = TimeCurrent(); } // // if the point's price is not set, it will have Bid value ... if (!price) { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); } } // // Horizontal Line Functions ... // // Create, Draw the horizontal line ... bool DrawHorizontalLine( const long chartID = 0, // chart's ID const string name = "HLine", // line name const int subWindow = 0, // subwindow index double price = 0, // line price const color clr = clrRed, // line color const ENUM_LINE_STYLE style = STYLE_SOLID, // line style const int width = 1, // line width const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = false, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // if the price is not set, set it at the current Bid price level ... if (!price) { price = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create a horizontal line ... result = ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price); if (!result) { return result; } // // set line color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set line display style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set line width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the line by mouse // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move horizontal line ... bool MoveHorizontalLine( const long chartID = 0, // chart's ID const string name = "HLine", // line name double price = 0 // line price ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if the line price is not set, move it to the current Bid price level ... if (!price) { price = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // move a horizontal line ... result = ObjectMove(chartID, objName, 0, 0, price); // return result; } // // Delete a horizontal line ... bool DeleteHorizontalLine( const long chartID = 0, // chart's ID const string name = "HLine" // line name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete a horizontal line ... result = ObjectDelete(chartID, objName); // return result; } // // Vertical Line Functions ... // // Create the vertical line ... bool DrawVerticalLine( const long chartID = 0, // chart's ID const string name = "VLine", // line name const int subWindow = 0, // subwindow index datetime time = 0, // line time const color clr = clrRed, // line color const ENUM_LINE_STYLE style = STYLE_SOLID, // line style const int width = 1, // line width const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = false, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // if the line time is not set, draw it via the last bar ... if (!time) { time = TimeCurrent(); } // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create a vertical line ... result = ObjectCreate(chartID, objName, OBJ_VLINE, subWindow, time, 0); if (!result) { return result; } // // set line color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set line display style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set line width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the line by mouse // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move the vertical line ... bool MoveVerticalLine( const long chartID = 0, // chart's ID const string name = "VLine", // line name datetime time = 0 // line time ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if line time is not set, move the line to the last bar ... if (!time) { time = TimeCurrent(); } // // move the vertical line ... result = ObjectMove(chartID, objName, 0, time, 0); // return result; } // // Delete the vertical line ... bool DeleteVerticalLine( const long chartID = 0, // chart's ID const string name = "VLine" // line name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the vertical line ... result = ObjectDelete(chartID, objName); // return result; } // // Rectangle Functions ... // // Create rectangle by the given coordinates ... bool DrawRectangle( const long chartID = 0, // chart's ID const string name = "Rectangle", // rectangle name const int subWindow = 0, // subwindow index datetime time1 = 0, // down first point time double price1 = 0, // down first point price datetime time2 = 0, // up second point time double price2 = 0, // up second point price const color clr = clrRed, // rectangle color const ENUM_LINE_STYLE style = STYLE_SOLID, // style of rectangle lines const int width = 1, // width of rectangle lines const bool fill = false, // filling rectangle with color const bool back = false, // in the background const bool selection = true, // highlight to move const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // Set anchor points' coordinates if they are not set ... ChangeRectangleEmptyPoints(time1, price1, time2, price2); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // Create a rectangle by the given coordinates ... result = ObjectCreate( chartID, objName, OBJ_RECTANGLE, subWindow, time1, price1, time2, price2 // ); if (!result) { return result; } // // Set rectangle color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // Set the style of rectangle lines ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // Set width of the rectangle lines ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // Enable (true) or disable (false) the mode of filling the rectangle ... ObjectSetInteger(chartID, objName, OBJPROP_FILL, fill); // // Display in the foreground (false) or background (true) ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // Enable (true) or disable (false) the mode of highlighting the rectangle for moving // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); // ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // Hide (true) or display (false) graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // Set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // Successful execution return result; } // // Move the rectangle anchor point ...s bool RectanglePointChange( const long chartID = 0, // chart's ID const string name = "Rectangle", // rectangle name const int pointIndex = 0, // anchor point index datetime time = 0, // anchor point time coordinate double price = 0 // anchor point price coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if point position is not set, move it to the current bar having Bid price ... if (!time) { time = TimeCurrent(); } // if (!price) { price = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // Move the anchor point ... result = ObjectMove(chartID, objName, pointIndex, time, price); // return result; } // // Delete the rectangle ... bool DeleteRectangle( const long chartID = 0, // chart's ID const string name = "Rectangle" // rectangle name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // result = ObjectDelete(chartID, objName); // return result; } // // Check the values of rectangle's anchor points and set default // values for empty ones void ChangeRectangleEmptyPoints( datetime &time1, double &price1, datetime &time2, double &price2 // ) { // // if the first point's time is not set, it will be on the current bar ... if (!time1) { time1 = TimeCurrent(); } // // if the first point's price is not set, it will have Bid value ... if (!price1) { price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // if the second point's time is not set, it is located 9 bars left from the second one ... if (!time2) { // // array for receiving the open time of the last 10 bars ... datetime temp[10]; CopyTime(Symbol(), Period(), time1, 10, temp); // // set the second point 9 bars left from the first one ... time2 = temp[0]; } // // if the second point's price is not set, move it 300 points lower than the first one ... if (!price2) { price2 = price1 - 300 * SymbolInfoDouble(Symbol(), SYMBOL_POINT); } } // // RectangleLabel Functions ... // // Create Rectangle Label Object ... bool DrawRectangleLabel( const long chartID = 0, // chart's ID const string name = "RectLabel", // label name const int subWindow = 0, // subwindow index const int x = 0, // X coordinate const int y = 0, // Y coordinate const int width = 50, // width const int height = 18, // height const color bgColor = clrWhiteSmoke, // background color const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring const color clr = clrRed, // flat border color (Flat) const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style const int lineWidth = 1, // flat border width const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = false, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create a rectangle label result = ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0); if (!result) { return result; } // // set label coordinates ... ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); // // set label size ... ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); // // set background color ... ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); // // set border type ... ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); // // set the chart's corner, relative to which point coordinates are defined ... ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); // // set flat border color (in Flat mode) ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set flat border line style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set flat border width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the label by mouse ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move Rectangle Label .. bool MoveRectangleLabel( const long chartID = 0, // chart's ID const string name = "RectLabel", // label name const int x = 0, // X coordinate const int y = 0 // Y coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // move the rectangle label ... result = ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); if (!result) { return result; } // result = ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); // return result; } // // Delete the rectangle label ... bool DeleteRectangleLabel( const long chartID = 0, // chart's ID const string name = "RectLabel" // label name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the label ... result = ObjectDelete(chartID, objName); // return result; } // // Change Rectangle Label Size ... bool ChangeSizeRectangleLabel( const long chartID = 0, // chart's ID const string name = "RectLabel", // label name const int width = 50, // label width const int height = 18 // label height ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change label size ... result = ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); if (!result) { return result; } // result = ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); // return result; } // // Change rectangle label border type ... bool RectLabelChangeBorderType( const long chartID = 0, // chart's ID const string name = "RectLabel", // label name const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change border type ... result = ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); // return result; } // // TrendLine Funcions ... // // Create a trend line by the given coordinates ... bool DrawTrendLine( const long chartID = 0, // chart's ID const string name = "TrendLine", // line name const int subWindow = 0, // subwindow index datetime time1 = 0, // first point time double price1 = 0, // first point price datetime time2 = 0, // second point time double price2 = 0, // second point price const color clr = clrYellow, // line color const ENUM_LINE_STYLE style = STYLE_SOLID, // line style const int width = 1, // line width const bool back = false, // in the background const bool selection = false, // highlight to move const bool rayRight = false, // line's continuation to the right const bool hidden = false, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // set anchor points' coordinates if they are not set ... ChangeTrendLineEmptyPoints( time1, price1, time2, price2); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create a trend line by the given coordinates ... result = ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2); if (!result) { return result; } // // set line color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set line display style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set line width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the line by mouse // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // enable true or disable false the mode of continuation of the line's display to the right ... ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move trend line anchor point ... | bool ChangeTrendLinePoint( const long chartID = 0, // chart's ID const string name = "TrendLine", // line name const int pointindex = 0, // anchor point index datetime time = 0, // anchor point time coordinate double price = 0 // anchor point price coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if point position is not set, move it to the current bar having Bid price ... if (!time) { time = TimeCurrent(); } // if (!price) { price = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // move trend line's anchor point ... result = ObjectMove(chartID, objName, pointindex, time, price); // return result; } // // The function deletes the trend line from the chart ... bool DeleteTrendLine( const long chartID = 0, // chart's ID const string name = "TrendLine" // line name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete a trend line ... result = ObjectDelete(chartID, objName); // return result; } // // Check the values of trend line's anchor points and set default ... // values for empty ones ... void ChangeTrendLineEmptyPoints( datetime &time1, double &price1, datetime &time2, double &price2 // ) { // // if the first point's time is not set, it will be on the current bar ... if (!time1) { time1 = TimeCurrent(); } // // if the first point's price is not set, it will have Bid value ... if (!price1) { price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); } // // if the second point's time is not set, it is located 9 bars left from the second one ... if (!time2) { // // array for receiving the open time of the last 10 bars ... datetime temp[10]; CopyTime(Symbol(), Period(), time1, 10, temp); // // set the second point 9 bars left from the first one ... time2 = temp[0]; } // // if the second point's price is not set, it is equal to the first point's one ... if (!price2) { price2 = price1; } } // // Text Functions ... // // Create and Draw a Text Object ... bool DrawText( const long chartID = 0, // chart's ID const string name = "Text", // object name const int subWindow = 0, // subwindow index datetime time = 0, // anchor point time double price = 0, // anchor point price const string text = "Text", // the text itself const string font = "Arial", // font const int fontSize = 10, // font size const color clr = clrRed, // color const double angle = 0.0, // text slope const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // set anchor point coordinates if they are not set ... ChangeTextEmptyPoint(time, price); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // // create Text object result = ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price); if (!result) { return result; } // // set the text ... ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // // set text font ... ObjectSetString(chartID, objName, OBJPROP_FONT, font); // // set font size ... ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); // // set the slope angle of the text ... ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); // // set anchor type ... ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); // // set color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving the object by mouse ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Move the anchor point ... bool MoveText( const long chartID = 0, // chart's ID const string name = "Text", // object name datetime time = 0, // anchor point time coordinate double price = 0 // anchor point price coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // // if point position is not set, move it to the current bar having Bid price if (!time) { time = TimeCurrent(); } // if (!price) { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); } // // move the anchor point ... result = ObjectMove(chartID, objName, 0, time, price); // return result; } // // Change the object text ... bool ChangeText( const long chartID = 0, // chart's ID const string name = "Text", // object name const string text = "Text" // text ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change object text ... result = ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // return result; } // // Delete Text object ... bool DeleteText( const long chartID = 0, // chart's ID const string name = "Text" // object name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the object ... result = ObjectDelete(chartID, objName); // return result; } // // Check anchor point values and set default values // for empty ones ... void ChangeTextEmptyPoint( datetime &time, double &price // ) { // // if the point's time is not set, it will be on the current bar ... if (!time) { time = TimeCurrent(); } // // if the point's price is not set, it will have Bid value ... if (!price) { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); } } // // Fibonacchi Functions ... // // Create Fibonacci Retracement by the given coordinates ... bool DrawFibonacci( const long chartID = 0, // chart's ID const string name = "Fibonacci", // object name const int subWindow = 0, // subwindow index datetime time1 = 0, // first point time double price1 = 0, // first point price datetime time2 = 0, // second point time double price2 = 0, // second point price const color clr = clrRed, // object color const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style const int width = 1, // object line width const bool back = false, // in the background const bool selection = true, // highlight to move const bool rayRight = false, // object's continuation to the right const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // set anchor points' coordinates if they are not set ... ChangeFibonacciEmptyPoints(time1, price1, time2, price2); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // Create Fibonacci Retracement by the given coordinates ... result = ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2); if (!result) { return result; } // // set color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set line style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set line width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of highlighting the channel for moving // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // enable true or disable false the mode of continuation of the object's display to the right ... ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution ... return result; } // // Create Fibonacci Retracement by the given coordinates ... bool DrawCustomFibonacci( // int levels, // number of level lines double &values[], // values of level lines color &colors[], // color of level lines ENUM_LINE_STYLE &styles[], // style of level lines int &widths[], // width of level lines string &descriptions[], // level Descriptions // const long chartID = 0, // chart's ID const string name = "Fibonacci", // object name const int subWindow = 0, // subwindow index datetime time1 = 0, // first point time double price1 = 0, // first point price datetime time2 = 0, // second point time double price2 = 0, // second point price const color clr = clrAqua, // object color const ENUM_LINE_STYLE style = STYLE_DOT, // object line style const int width = 1, // object line width const bool back = false, // in the background const bool selection = true, // highlight to move const bool rayRight = false, // object's continuation to the right const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // set anchor points' coordinates if they are not set ... ChangeFibonacciEmptyPoints(time1, price1, time2, price2); // // Normalize Name ... string objName = drawPrefix + "_" + name; // // Create Fibonacci Retracement by the given coordinates ... result = ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2); if (!result) { return result; } // // set color ... ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set line style ... ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); // // set line width ... ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ... ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of highlighting the channel for moving // when creating a graphical object using ObjectCreate function, the object cannot be // highlighted and moved by default. Inside this method, selection parameter // is true by default making it possible to highlight and move the object ... ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // enable true or disable false the mode of continuation of the object's display to the right ... ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); // // hide true or display false graphical object name in the object list ... ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ... ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // Change Levels Of Fibonacci ... result = FibonacciLevelsSet( levels, values, colors, styles, widths, descriptions, chartID, objName); // // successful execution ... return result; } // // Set number of levels and their parameters ... bool FibonacciLevelsSet( int levels, // number of level lines double &values[], // values of level lines color &colors[], // color of level lines ENUM_LINE_STYLE &styles[], // style of level lines int &widths[], // width of level lines string &descriptions[], // level Descriptions const long chartID = 0, // chart's ID const string name = "Fibonacci" // object name ) { // bool result = false; // // check array sizes ... result = levels == ArraySize(colors) && levels == ArraySize(styles) && levels == ArraySize(widths) && levels == ArraySize(widths); if (!result) { return result; } // // Normalize Name ... string objName = drawPrefix + "_" + name; // // set the number of levels ... ObjectSetInteger(chartID, objName, OBJPROP_LEVELS, levels); // // set the properties of levels in the loop ... for (int i = 0; i < levels; i++) { // // level value ... ObjectSetDouble(chartID, objName, OBJPROP_LEVELVALUE, i, values[i]); // // level color ... ObjectSetInteger(chartID, objName, OBJPROP_LEVELCOLOR, i, colors[i]); // // level style ... ObjectSetInteger(chartID, objName, OBJPROP_LEVELSTYLE, i, styles[i]); // // level width ... ObjectSetInteger(chartID, objName, OBJPROP_LEVELWIDTH, i, widths[i]); // // level description ... // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); ObjectSetString(chartID, objName, OBJPROP_LEVELTEXT, i, descriptions[i]); } // // successful execution ... return result; } // // Move Fibonacci Retracement anchor point ... bool FibonacciPointChange( const long chartID = 0, // chart's ID const string name = "Fibonacci", // object name const int pointIndex = 0, // anchor point index datetime time = 0, // anchor point time coordinate double price = 0 // anchor point price coordinate ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if point position is not set, move it to the current bar having Bid price ... if (!time) { time = TimeCurrent(); } // if (!price) { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); } // // move the anchor point ... result = ObjectMove(chartID, objName, pointIndex, time, price); // return result; } // // Delete Fibonacci Retracement ... bool DeleteFibonachi( const long chartID = 0, // chart's ID const string name = "Fibonacci" // object name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the object ... result = ObjectDelete(chartID, objName); // return result; } // // Check the values of Fibonacci Retracement anchor points and set // default values for empty ones ... void ChangeFibonacciEmptyPoints( datetime &time1, double &price1, datetime &time2, double &price2 // ) { // // if the second point's time is not set, it will be on the current bar ... if (!time2) { time2 = TimeCurrent(); } // // if the second point's price is not set, it will have Bid value ... if (!price2) { price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); } // // if the first point's time is not set, it is located 9 bars left from the second one ... if (!time1) { // // array for receiving the open time of the last 10 bars ... datetime temp[10]; CopyTime(Symbol(), Period(), time2, 10, temp); // // set the first point 9 bars left from the second one ... time1 = temp[0]; } // // if the first point's price is not set, move it 200 points below the second one ... if (!price1) { price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); } } // // Event Functions ... // // Create an Event ... bool EventCreate( const long chartID = 0, // chart's ID const string name = "Event", // object name const int subWindow = 0, // subwindow index const string text = "Content", // event text datetime time = 0, // anchor point time const color clr = clrRed, // color const int width = 1, // point width when highlighted const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // if (!time) { time = TimeCurrent(); } // // Normalize Name ... string objName = drawPrefix + "_" + name; // result = ObjectCreate(chartID, objName, OBJ_EVENT, subWindow, time, 0); if (!result) { return result; } // // set event text ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // // set color ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set anchor point width if the object is highlighted ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); // // display in the foreground false or background true ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // enable true or disable false the mode of moving event by mouse ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // // successful execution return result; } // // Change Event object text bool EventTextChange( const long chartID = 0, // chart's ID const string name = "Event", // event name const string text = "Content" // text ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change object text result = ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // return result; } // // Move Event object bool EventMove( const long chartID = 0, // chart's ID const string name = "Event", // event name datetime time = 0 // time ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // if time is not set, move event to the last bar if (!time) { time = TimeCurrent(); } // // move the object result = ObjectMove(chartID, objName, 0, time, 0); // return result; } // // Delete Event object bool EventDelete( const long chartID = 0, // chart's ID const string name = "Event" // event name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the object result = ObjectDelete(chartID, objName); // return result; } // // Button Functions ... // // Create the button ... bool ButtonCreate( const long chartID = 0, // chart's ID const string name = "Button", // button name const int subWindow = 0, // subwindow index const int x = 0, // X coordinate const int y = 0, // Y coordinate const int width = 50, // button width const int height = 15, // button height const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring const string text = "Button", // text const string font = "Arial", // font const int fontSize = 8, // font size const color clr = clrBlack, // text color const color bgColor = clrLightGray, // background color const color borderColor = clrNONE, // border color const bool state = false, // pressed/released const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = true, // hidden in the object list const long zOrder = 0 // priority for mouse click ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // create the button result = ObjectCreate(chartID, objName, OBJ_BUTTON, subWindow, 0, 0); if (!result) { return result; } // // set button coordinates ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); // // set button size ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); // // set the chart's corner, relative to which point coordinates are defined ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); // // set the text ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // // set text font ObjectSetString(chartID, objName, OBJPROP_FONT, font); // // set font size ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); // // set text color ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); // // set background color ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); // // set border color ObjectSetInteger(chartID, objName, OBJPROP_BORDER_COLOR, borderColor); // // display in the foreground false or background true ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); // // set button state ObjectSetInteger(chartID, objName, OBJPROP_STATE, state); // // enable true or disable false the mode of moving the button by mouse ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); // // hide true or display false graphical object name in the object list ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); // // set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); // return result; } // // Move the button ... bool ButtonMove( const long chartID = 0, // chart's ID const string name = "Button", // button name const int x = 0, // X coordinate const int y = 0 // Y coordinate ) { // bool result = false; // // move the button // // Normalize Name ... string objName = drawPrefix + "_" + name; // result = ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); if (!result) { return result; } // result = ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); // return result; } // // Change button size ... bool ButtonChangeSize( const long chartID = 0, // chart's ID const string name = "Button", // button name const int width = 50, // button width const int height = 18 // button height ) { // bool result = false; // // change the button size // // Normalize Name ... string objName = drawPrefix + "_" + name; // result = ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); if (!result) { return result; } // result = ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); // return result; } // // Change corner of the chart for binding the button ... bool ButtonChangeCorner( const long chartID = 0, // chart's ID const string name = "Button", // button name const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change anchor corner result = ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); // return result; } // // Change button text ... bool ButtonTextChange( const long chartID = 0, // chart's ID const string name = "Button", // button name const string text = "Text" // text ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // change object text result = ObjectSetString(chartID, objName, OBJPROP_TEXT, text); // return result; } // // Delete the button ... bool ButtonDelete( const long chartID = 0, // chart's ID const string name = "Button" // button name ) { // bool result = false; // // Normalize Name ... string objName = drawPrefix + "_" + name; // // delete the button result = ObjectDelete(chartID, objName); // return result; } // // Chart Style Drawers ... // // Apply Styles On Chart ... void ApplyChartStyle( long mChartId = -1, // chart's ID ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode bool mShowBidLine = true, // show bid line bool mShowAskLine = true, // show ask line bool mShowGrid = false, // show grids on chart bool mShowVolumes = false, // show volumes bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) bool mAutoScroll = true, // chart autoscroll bool mQuickNavigation = true, // chart quick navigation state color mForeGroundColor = clrWhite, // chart's foreground color color mBackGroundColor = clrBlack, // chart's background color color mUpColor = clrGreen, // Up Color color mDownColor = clrRed, // Down Color color mBullishColor = clrGreen, // Bullish color color mBearishColor = clrRed, // Bearish color color mGridColor = clrGray, // grid color color mBidLineColor = clrGray, // bid line color color mAskLineColor = clrRed, // ask line color color mLineColor = clrLime, // line mMode and doji candlestick color color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) color mVolumesColor = clrGreen // volumes color ) { // // Validate Args ... if (mChartId == -1) { mChartId = 0; } // ChartSetInteger(mChartId, CHART_MODE, mMode); ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); } // // Tools ... // // Retrieve Chart Size ... bool GetChartSize( XSize &result, // Holds Result ... long chartID = 0 // Specified Chart ID ... ) { // bool mResult = false; // mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); if (!mResult) { return mResult; } // mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); // return mResult; } ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-enums.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XEnumsLib // Description: provide all commonly used functions ... // // // 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 // // START Price Type ... // // // Availables Price Types ... enum ENUM_X_PRICE { X_PRICE_NONE, // None X_PRICE_HIGH, // High X_PRICE_OPEN, // Open X_PRICE_CLOSE, // Close X_PRICE_LOW, // Low X_PRICE_UP, // Body Up X_PRICE_DOWN, // Body Down X_PRICE_MEDIAN, // Median X_PRICE_BODY_MEDIAN, // Body Median X_PRICE_TYPICAL, // Typical X_PRICE_WEIGHTED // Weighted }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_PRICE member ... * * @return ( bool ) */ bool IsValid(ENUM_X_PRICE value) { // bool result = false; // result = value != NULL && value != X_PRICE_NONE; // return result; } bool IsXValid(ENUM_X_PRICE value) { return IsValid(value); } /** * Converts Series Mode to ENUM_X_PRICE ... * * @param value: ENUM_SERIESMODE member ... * * @return ( ENUM_X_PRICE ) */ ENUM_X_PRICE ToXPrice(ENUM_SERIESMODE value) { // ENUM_X_PRICE result = X_PRICE_CLOSE; // switch (value) { // // High ... case MODE_HIGH: result = X_PRICE_HIGH; break; // // Open ... case MODE_OPEN: result = X_PRICE_OPEN; break; // // Low ... case MODE_LOW: result = X_PRICE_LOW; break; // // Close ... // Default ... case MODE_CLOSE: default: result = X_PRICE_CLOSE; break; } // return result; } /** * Converts Applied Price to ENUM_X_PRICE ... * * @param value: ENUM_APPLIED_PRICE member ... * * @return ( ENUM_X_PRICE ) */ ENUM_X_PRICE ToXPrice(ENUM_APPLIED_PRICE value) { // ENUM_X_PRICE result = X_PRICE_NONE; // switch (value) { // case PRICE_HIGH: result = X_PRICE_HIGH; break; // case PRICE_OPEN: result = X_PRICE_OPEN; break; // case PRICE_CLOSE: result = X_PRICE_CLOSE; break; // case PRICE_LOW: result = X_PRICE_LOW; break; // case PRICE_MEDIAN: result = X_PRICE_MEDIAN; break; // case PRICE_TYPICAL: result = X_PRICE_TYPICAL; break; // case PRICE_WEIGHTED: result = X_PRICE_WEIGHTED; break; } // return result; } /** * Converts Price Type to Applied Price ... * * @param value: ENUM_X_PRICE member ... * * @return ( ENUM_APPLIED_PRICE ) */ ENUM_APPLIED_PRICE ToAppliedPrice(ENUM_X_PRICE value) { // // Default ... ENUM_APPLIED_PRICE result = PRICE_CLOSE; // if (!IsValid(value) || value == X_PRICE_UP || value == X_PRICE_DOWN || value == X_PRICE_BODY_MEDIAN) { return result; } // switch (value) { // case X_PRICE_HIGH: result = PRICE_HIGH; break; // case X_PRICE_OPEN: result = PRICE_OPEN; break; // case X_PRICE_CLOSE: result = PRICE_CLOSE; break; // case X_PRICE_LOW: result = PRICE_LOW; break; // case X_PRICE_MEDIAN: result = PRICE_MEDIAN; break; // case X_PRICE_TYPICAL: result = PRICE_TYPICAL; break; // case X_PRICE_WEIGHTED: result = PRICE_WEIGHTED; break; } // return result; } ENUM_APPLIED_PRICE ToXAppliedPrice(ENUM_X_PRICE value) { return ToAppliedPrice(value); } /** * Converts To String ... * * @param value: ENUM_X_PRICE member ... * * @return ( string ) */ string ToString(ENUM_X_PRICE value) { // string result = NULL; // switch (value) { // case X_PRICE_NONE: result = "None"; break; // case X_PRICE_HIGH: result = "High"; break; // case X_PRICE_OPEN: result = "Open"; break; // case X_PRICE_CLOSE: result = "Close"; break; // case X_PRICE_LOW: result = "Low"; break; // case X_PRICE_UP: result = "Body Up"; break; // case X_PRICE_DOWN: result = "Body Down"; break; // case X_PRICE_MEDIAN: result = "Median"; break; // case X_PRICE_BODY_MEDIAN: result = "Body Median"; break; // case X_PRICE_TYPICAL: result = "Typical"; break; // case X_PRICE_WEIGHTED: result = "Weighted"; break; } // return result; } string ToXString(ENUM_X_PRICE value) { return ToString(value); } // // END Price Type ... // // // START Boundary Price Type ... // // // Available Boundary Price Types ... enum ENUM_X_BOUNDARY_PRICE { X_BOUNDARY_PRICE_NONE, // None X_BOUNDARY_PRICE_UP_DOWN, // Up/Down X_BOUNDARY_PRICE_HIGH_LOW, // High/Low }; /** * Validate ... * * @param value: ENUM_X_BOUNDARY_PRICE member ... * * @return ( bool ) */ bool IsValid(ENUM_X_BOUNDARY_PRICE value) { // bool result = false; // result = value != NULL && value != X_BOUNDARY_PRICE_NONE; // return result; } bool IsXValid(ENUM_X_BOUNDARY_PRICE value) { return IsValid(value); } bool IsSpecifiedValid(ENUM_X_BOUNDARY_PRICE value) { return IsValid(value); } /** * Converts To String ... * * @param value: ENUM_X_BOUNDARY_PRICE member ... * * @return ( string ) */ string ToString(ENUM_X_BOUNDARY_PRICE value) { // string result = NULL; // if (!IsValid(value)) { value = X_BOUNDARY_PRICE_NONE; } // result = EnumToString(value); // return result; } string ToXString(ENUM_X_BOUNDARY_PRICE value) { return ToString(value); } // // END Boundary Price Type ... // // // START Direction ... // // // Directions ... enum ENUM_X_DIRECTION { X_DIRECTION_ALL, // All X_DIRECTION_NONE, // None X_DIRECTION_BULLISH, // Bullish X_DIRECTION_BEARISH, // Bearish }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool IsValid(ENUM_X_DIRECTION value) { // bool result = false; // result = value != NULL && value != X_DIRECTION_NONE; // return result; } bool IsXValid(ENUM_X_DIRECTION value) { return IsValid(value); } bool IsSpecifiedValid(ENUM_X_DIRECTION value) { return IsValid(value); } /** * Validate value Has Specified Direction ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool HasDirection(ENUM_X_DIRECTION value) { // bool result = false; // result = IsValid(value) && value != X_DIRECTION_ALL; // return result; } /** * Check a Direction is Bullish or not ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool IsBullish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BULLISH; // return result; } bool IsXBullish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BULLISH; // return result; } bool IsSpecifiedBullish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BULLISH; // return result; } /** * Check a Direction is Bearish or not ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool IsBearish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BEARISH; // return result; } bool IsXBearish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BEARISH; // return result; } bool IsSpecifiedBearish(ENUM_X_DIRECTION value) { // bool result = false; // result = value == X_DIRECTION_BEARISH; // return result; } /** * Converts Specified Direction to Opposit ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( ENUM_X_DIRECTION ) */ ENUM_X_DIRECTION Opposit(ENUM_X_DIRECTION value) { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // if (!HasDirection(value)) { return result; } // result = IsBullish(value) ? X_DIRECTION_BEARISH : X_DIRECTION_BULLISH; // return result; } ENUM_X_DIRECTION XOpposit(ENUM_X_DIRECTION value) { return Opposit(value); } /** * Converts To String ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( string ) */ string ToString(ENUM_X_DIRECTION value) { // string result = NULL; // switch (value) { case X_DIRECTION_ALL: result = "ALL"; break; case X_DIRECTION_NONE: result = "NONE"; break; case X_DIRECTION_BULLISH: result = "BULLISH"; break; case X_DIRECTION_BEARISH: result = "BEARISH"; break; } // return result; } string ToXString(ENUM_X_DIRECTION value) { return ToString(value); } // // END Direction ... // // // START Fibo Level ... // // // Fibonacci Levels ... enum ENUM_X_FIBO_LEVELS { X_FIBO_LEVEL_236, // 0.236 X_FIBO_LEVEL_270, // 0.27 X_FIBO_LEVEL_382, // 0.382 X_FIBO_LEVEL_500, // 0.5 X_FIBO_LEVEL_618, // 0.618 X_FIBO_LEVEL_730, // 0.730 X_FIBO_LEVEL_764, // 0.764 X_FIBO_LEVEL_786, // 0.786 }; // // Extensions ... /** * Converts To String ... * * @param value: ENUM_X_FIBO_LEVELS member ... * * @return ( string ) */ string ToString(ENUM_X_FIBO_LEVELS value) { // string result = NULL; // switch (value) { // case X_FIBO_LEVEL_236: result = "0.236"; break; // case X_FIBO_LEVEL_270: result = "0.270"; break; // case X_FIBO_LEVEL_382: result = "0.382"; break; // case X_FIBO_LEVEL_500: result = "0.500"; break; // case X_FIBO_LEVEL_618: result = "0.618"; break; // case X_FIBO_LEVEL_730: result = "0.730"; break; // case X_FIBO_LEVEL_764: result = "0.764"; break; // case X_FIBO_LEVEL_786: result = "0.786"; break; } // return result; } string ToXString(ENUM_X_FIBO_LEVELS value) { return ToString(value); } /** * Converts To String ... * * @param value: ENUM_X_FIBO_LEVELS member ... * * @return ( double ) */ double GetFiboLevelValue(ENUM_X_FIBO_LEVELS value) { // double result = 0; // switch (value) { // case X_FIBO_LEVEL_236: result = 0.236; break; // case X_FIBO_LEVEL_270: result = 0.270; break; // case X_FIBO_LEVEL_382: result = 0.382; break; // case X_FIBO_LEVEL_500: result = 0.500; break; // case X_FIBO_LEVEL_618: result = 0.618; break; // case X_FIBO_LEVEL_730: result = 0.730; break; // case X_FIBO_LEVEL_764: result = 0.764; break; // case X_FIBO_LEVEL_786: result = 0.786; break; } // return result; } // // END Fibo Level ... // // // START Swing Types ... // // // Swing Types ... enum ENUM_X_SWING_TYPE { X_SWING_NONE, // None X_SWING_LOW, // Swing Low X_SWING_HIGH, // Swing High }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool IsValid(ENUM_X_SWING_TYPE value) { // bool result = false; // result = value != NULL && value != X_SWING_NONE; // return result; } bool IsXValid(ENUM_X_SWING_TYPE value) { return IsValid(value); } /** * Converts To String ... * * @param value: ENUM_X_SWING_TYPE member ... * * @return ( string ) */ string ToString(ENUM_X_SWING_TYPE value) { // string result = NULL; // switch (value) { // case X_SWING_NONE: result = "None"; break; // case X_SWING_LOW: result = "Swing Low"; break; // case X_SWING_HIGH: result = "Swing High"; break; } // return result; } string ToXString(ENUM_X_SWING_TYPE value) { return ToString(value); } /** * Converts To ENUM_SERIESMODE ... * * @param value: ENUM_X_SWING_TYPE member ... * * @return ( ENUM_SERIESMODE ) */ ENUM_SERIESMODE ToSeriesMode(ENUM_X_SWING_TYPE value) { // ENUM_SERIESMODE result = MODE_HIGH; // switch (value) { // case X_SWING_HIGH: result = MODE_HIGH; break; // case X_SWING_LOW: default: result = MODE_LOW; break; } // return result; } ENUM_SERIESMODE ToXSeriesMode(ENUM_X_SWING_TYPE value) { return ToSeriesMode(value); } // // END Swing Types ... // // // START Period Method ... // // // Period Calculation Method ... enum ENUM_X_PERIOD_METHOD { X_PERIOD_NONE, // None X_PERIOD_AUTO, // Auto Select X_PERIOD_MANUALLY // Manually }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_PERIOD_METHOD member ... * * @return ( bool ) */ bool IsValid(ENUM_X_PERIOD_METHOD value) { // bool result = false; // result = value != NULL && value != X_PERIOD_NONE; // return result; } bool IsXValid(ENUM_X_PERIOD_METHOD value) { return IsValid(value); } /** * Converts To String ... * * @param value: ENUM_X_PERIOD_METHOD member ... * * @return ( string ) */ string ToString(ENUM_X_PERIOD_METHOD value) { // string result = NULL; // switch (value) { // case X_PERIOD_NONE: result = "None"; break; // case X_PERIOD_AUTO: result = "Auto Select"; break; // case X_PERIOD_MANUALLY: result = "Manually"; break; } // return result; } string ToXString(ENUM_X_PERIOD_METHOD value) { return ToString(value); } // // END Period Method ... // // // START Market Cycles ... // // // Market Cycles ... enum ENUM_X_MARKET_CYCLES { X_MARKET_CYCLE_UNKNOWN, // Unknown Cycle X_MARKET_CYCLE_SHORT, // Short Cycle X_MARKET_CYCLE_MEDIUM, // Medium Cycle X_MARKET_CYCLE_LONG, // Long Cycle X_MARKET_CYCLE_HIND, // Hind Cycle }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_MARKET_CYCLES member ... * * @return ( bool ) */ bool IsValid(ENUM_X_MARKET_CYCLES value) { // bool result = false; // result = // value != NULL && value != X_MARKET_CYCLE_UNKNOWN // ; // return result; } bool IsXValid(ENUM_X_MARKET_CYCLES value) { return IsValid(value); } bool IsSpecifiedValid(ENUM_X_MARKET_CYCLES value) { return IsValid(value); } /** * Converts an String to it's related Market Cycle ... * * @param value: string ... * * @return ( ENUM_X_MARKET_CYCLES ) */ ENUM_X_MARKET_CYCLES ToCycle(string value) { // ENUM_X_MARKET_CYCLES result = X_MARKET_CYCLE_UNKNOWN; // ENUM_X_MARKET_CYCLES cycles[]; int count = GetAllMarketCycles(cycles); for (int i = 0; i < count; i++) { // ENUM_X_MARKET_CYCLES iCycle = cycles[i]; string iStr = ToString(iCycle); // if (value == iStr) { // result = iCycle; break; } } // return result; } ENUM_X_MARKET_CYCLES ToXCycle(string value) { return ToCycle(value); } /** * Converts To String ... * * @param value: ENUM_X_MARKET_CYCLES member ... * * @return ( string ) */ string ToString(ENUM_X_MARKET_CYCLES value) { // string result = NULL; // switch (value) { // case X_MARKET_CYCLE_UNKNOWN: result = "Unknown Cycle"; break; // case X_MARKET_CYCLE_SHORT: result = "Short Cycle"; break; // case X_MARKET_CYCLE_MEDIUM: result = "Medium Cycle"; break; // case X_MARKET_CYCLE_LONG: result = "Long Cycle"; break; // case X_MARKET_CYCLE_HIND: result = "Hind Cycle"; break; } // return result; } string ToXString(ENUM_X_MARKET_CYCLES value) { return ToString(value); } /** * Retrieve All Availabled Market Cycles ... * * @param cycles: ENUM_X_MARKET_CYCLES member collection ... * * @return ( int ) */ int GetAllMarketCycles(ENUM_X_MARKET_CYCLES &cycles[]) { // ZeroMemory(cycles); ArrayResize(cycles, 0); // ArrayResize(cycles, ArraySize(cycles) + 1); cycles[ArraySize(cycles) - 1] = X_MARKET_CYCLE_UNKNOWN; // ArrayResize(cycles, ArraySize(cycles) + 1); cycles[ArraySize(cycles) - 1] = X_MARKET_CYCLE_SHORT; // ArrayResize(cycles, ArraySize(cycles) + 1); cycles[ArraySize(cycles) - 1] = X_MARKET_CYCLE_MEDIUM; // ArrayResize(cycles, ArraySize(cycles) + 1); cycles[ArraySize(cycles) - 1] = X_MARKET_CYCLE_LONG; // ArrayResize(cycles, ArraySize(cycles) + 1); cycles[ArraySize(cycles) - 1] = X_MARKET_CYCLE_HIND; // int result = ArraySize(cycles); // return result; } // // END Market Cycles ... // // // START Week Days ... // // // Week Days ... enum ENUM_X_WEEK_DAYS { X_WEEK_DAY_NONE = -1, // None X_WEEK_DAY_SUNDAY = 0, // Sunday X_WEEK_DAY_MONDAY = 1, // Monday X_WEEK_DAY_TUESDAY = 2, // Tuesday X_WEEK_DAY_WEDNESDAY = 3, // Wednesday X_WEEK_DAY_THURSDAY = 4, // Thursday X_WEEK_DAY_FRIDAY = 5, // Friday X_WEEK_DAY_SATURDAY = 6, // Saturday }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_WEEK_DAYS member ... * * @return ( bool ) */ bool IsValid(ENUM_X_WEEK_DAYS value) { // bool result = false; // result = // value != NULL && value != X_WEEK_DAY_NONE // ; // return result; } bool IsXValid(ENUM_X_WEEK_DAYS value) { return IsValid(value); } /** * Converts To String ... * * @param value: ENUM_X_WEEK_DAYS member ... * * @return ( string ) */ string ToString(ENUM_X_WEEK_DAYS value) { // string result = NULL; // switch (value) { // case X_WEEK_DAY_NONE: result = "None"; break; // case X_WEEK_DAY_SUNDAY: result = "Sunday"; break; // case X_WEEK_DAY_MONDAY: result = "Monday"; break; // case X_WEEK_DAY_TUESDAY: result = "Tuesday"; break; // case X_WEEK_DAY_WEDNESDAY: result = "Wednesday"; break; // case X_WEEK_DAY_THURSDAY: result = "Thursday"; break; // case X_WEEK_DAY_FRIDAY: result = "Friday"; break; // case X_WEEK_DAY_SATURDAY: result = "Saturday"; break; } // return result; } string ToXString(ENUM_X_WEEK_DAYS value) { return ToString(value); } // // END Week Days ... // // // START Ma Methods ... // // // Ma Methods ... enum ENUM_X_MA_METHOD { X_MA_MODE_NONE, // None X_MA_MODE_SMA, // SMA X_MA_MODE_EMA, // EMA X_MA_MODE_LWMA, // LWMA X_MA_MODE_SMMA, // SMMA }; // // Extensions ... /** * Validate ... * * @param value: ENUM_X_MA_METHOD member ... * * @return ( bool ) */ bool IsValid(ENUM_X_MA_METHOD value) { // bool result = false; // result = // value != NULL && value != X_MA_MODE_NONE // ; // return result; } bool IsXValid(ENUM_X_MA_METHOD value) { return IsValid(value); } /** * Converts To String ... * * @param value: ENUM_X_MA_METHOD member ... * * @return ( string ) */ string ToString(ENUM_X_MA_METHOD value) { // string result = NULL; // switch (value) { // case X_MA_MODE_NONE: result = "None"; break; // case X_MA_MODE_SMA: result = "SMA"; break; // case X_MA_MODE_EMA: result = "EMA"; break; // case X_MA_MODE_LWMA: result = "LWMA"; break; // case X_MA_MODE_SMMA: result = "SMMA"; break; } // return result; } string ToXString(ENUM_X_MA_METHOD value) { return ToString(value); } /** * Converts MA Method ... **/ ENUM_MA_METHOD ToXMaMethod(ENUM_X_MA_METHOD value) { // ENUM_MA_METHOD result = MODE_SMA; // if (!IsXValid(value)) { return result; } // switch (value) { // case X_MA_MODE_EMA: result = MODE_EMA; break; // case X_MA_MODE_SMA: result = MODE_SMA; break; // case X_MA_MODE_LWMA: result = MODE_LWMA; break; // case X_MA_MODE_SMMA: result = MODE_SMMA; break; } // return result; } ENUM_X_MA_METHOD ToXMaMethod(ENUM_MA_METHOD value) { // ENUM_X_MA_METHOD result = X_MA_MODE_NONE; // switch (value) { // case MODE_EMA: result = X_MA_MODE_EMA; break; // case MODE_SMA: result = X_MA_MODE_SMA; break; // case MODE_LWMA: result = X_MA_MODE_LWMA; break; // case MODE_SMMA: result = X_MA_MODE_SMMA; break; } // return result; } // // END Ma Methods ... // // // START XPivots ... // // enum ENUM_X_PIVOT_TYPE { X_PIVOT_TYPE_NONE = 0, // None X_PIVOT_TYPE_PEAK = 1, // PEAK X_PIVOT_TYPE_VALE = 2, // VALE }; /** * Validate ... * * @param value: ENUM_X_PIVOT_TYPE ... * * @return ( bool ) */ bool IsXValid(ENUM_X_PIVOT_TYPE value) { // bool result = false; // result = value != X_PIVOT_TYPE_NONE; // return result; } /** * Check Specified Type of Pivot is Peak or not ... * * @param value: ENUM_X_PIVOT_TYPE, Specified Type ... * * @return ( bool ) */ bool IsXPeak(ENUM_X_PIVOT_TYPE value) { // bool result = false; // result = IsXValid(value) && value == X_PIVOT_TYPE_PEAK; // return result; } /** * Check Specified Type of Pivot is Vale or not ... * * @param value: ENUM_X_PIVOT_TYPE, Specified Type ... * * @return ( bool ) */ bool IsXVale(ENUM_X_PIVOT_TYPE value) { // bool result = false; // result = IsXValid(value) && value == X_PIVOT_TYPE_VALE; // return result; } /** * Represent Specified ZigZag Point Type as String ... * * @param value: ENUM_X_PIVOT_TYPE ... * * @return ( string ) */ string ToXString(ENUM_X_PIVOT_TYPE value) { // string result = NULL; // switch (value) { // case X_PIVOT_TYPE_NONE: result = "XNONE"; break; // case X_PIVOT_TYPE_PEAK: result = "XPEAK"; break; // case X_PIVOT_TYPE_VALE: result = "XVALE"; break; } // return result; // return EnumToString(value); } // // END XPivots ... // // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-guard.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XGuardLib // Description: All models related to Guard ... // // // 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 "../Libraries/x-saherelm.common.lib.mq5" // // Enumeration ... // // Guard Actions ... enum ENUM_X_GUARD_ACTIONS { X_GUARD_ACTION_NONE, // Nothing to Do X_GUARD_ACTION_CLOSE, // Close Specified Position X_GUARD_ACTION_CLOSE_ALL, // Close All Positions X_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions X_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position X_GUARD_ACTION_CLOSE_IN_LOSTS, // Close All In Lost Position X_GUARD_ACTION_CLOSE_IN_PROFITS, // Close All In Profit Position X_GUARD_ACTION_CLOSE_IN_LOST_LONGS, // Close All In Lost Long Position X_GUARD_ACTION_CLOSE_IN_PROFIT_LONGS, // Close All In Profit Long Position X_GUARD_ACTION_CLOSE_IN_LOST_SHORTS, // Close All In Lost Short Position X_GUARD_ACTION_CLOSE_IN_PROFITS_SHORT, // Close All In Profit Short Position X_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position X_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position X_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position X_GUARD_ACTION_HEDGE, // Hedge Specified Positions }; // // Definitions ... // // Model a Guard Action ... struct XGuard { // // Props ... ENUM_X_GUARD_ACTIONS action; datetime time; // string symbol; string provider; ENUM_TIMEFRAMES period; // // Specified Position ... ulong ticket; // // Partial Close ... double volumeMultiplier; // // SL Trial ... double sl; // // TP Trial ... double tp; // bool force; // // Constructor ... XGuard() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // time = NULL; action = X_GUARD_ACTION_NONE; // symbol = NULL; period = NULL; provider = NULL; // ticket = 0; // volumeMultiplier = 0; // sl = 0; tp = 0; // force = false; // ZeroMemory(this); } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && IsSpecifiedValid(action) && IsSpecifiedValid(provider) // ; if (!result) { return result; } // // Validate Model Based On Specified Guard Actions ... // return result; } }; // // Extensions ... // bool IsValid(ENUM_X_GUARD_ACTIONS item) { // bool result = false; // result = item != X_GUARD_ACTION_NONE; // return result; } bool IsSpecifiedValid(ENUM_X_GUARD_ACTIONS item) { return IsValid(item); } /** * Add Guard to Collection ... * * @param guard: XGuard instance ... * @param guards: XGuard instance Collection ... * * @return ( int ) */ int AddGuard( XGuard &guard, XGuard &guards[] // ) { // int result = 0; // if (!guard.IsValid()) { return result; } // AddRef( guard, guards // ); // result = ArraySize(guards); // return result; } ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-ohcl.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XOHCLLib // Description: provide all commonly used functions ... // // // 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 // #include "../Libraries/x-saherelm.common.extensions.lib.mq5" // // Describe an Specific Candle ... struct XOHCL { // // Props ... // double high; double open; double close; double low; long volume; double spread; // string symbol; datetime time; ENUM_TIMEFRAMES period; // // Constructor ... XOHCL() { Clean(); } // // Init a Bar ... // Using Bar Index ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period int barIndex = 0 // Bar Index ) { // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // symbol = mSymbol; period = mPeriod; // time = iTime( mSymbol, mPeriod, barIndex // ); // open = iOpen( mSymbol, mPeriod, barIndex // ); open = NormalizePrice(open, mSymbol); // close = iClose( mSymbol, mPeriod, barIndex // ); close = NormalizePrice(close, mSymbol); // high = iHigh( mSymbol, mPeriod, barIndex // ); high = NormalizePrice(high, mSymbol); // low = iLow( mSymbol, mPeriod, barIndex // ); low = NormalizePrice(low, mSymbol); // spread = iSpread( mSymbol, mPeriod, barIndex // ); spread = NormalizePrice(spread, mSymbol); // volume = iTickVolume( mSymbol, mPeriod, barIndex // ); // bool result = IsValid(); // return result; } // // Init a Bar ... // Using Bar Time ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period datetime mTime = NULL // Bar Time ) { // mTime = NormalizeTime(mTime); // int barIndex = iBarShift( mSymbol, mPeriod, mTime, false // ); // bool result = Init( mSymbol, mPeriod, barIndex // ); // return result; } // // Tools ... // void Clean() { // low = 0; high = 0; open = 0; close = 0; spread = 0; volume = 0; // time = NULL; symbol = NULL; period = NULL; // ZeroMemory(this); } // // Validate Bar ... bool IsValid() { // bool result = false; // result = // low > 0 && high > 0 && open > 0 && close > 0 && volume > 0 // // TODO: Fix in Some Cases for Zero Spread ... // spread > 0 && // ; // return result; } // int TotalBars() { // int result = 0; // result = iBars( symbol, period // ); // return result; } // // Calculate X_PRICE Specified Type ... double GetPrice(ENUM_X_PRICE mPType) { // double result = 0; // if (!IsValid()) { return result; } // return GetAppliedPrice( mPType, open, high, low, close // ); } // // Retrieve Price base On Series Mode ... double GetPrice(ENUM_SERIESMODE mMode) { // ENUM_X_PRICE mType = ToXPrice(mMode); // return GetPrice(mType); } // // Calculate Applied Price ... double GetPrice(ENUM_APPLIED_PRICE mPType) { // ENUM_X_PRICE mType = ToXPrice(mPType); // return GetPrice(mType); } // // Find Specific Price ... bool FindHigherPriceBar( XOHCL &bar, double price, ENUM_X_PRICE _type = X_PRICE_HIGH // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int totalBars = TotalBars(); result = IsValidSize(totalBars); if (!result) { return result; } // int start = Index(); int maxAllowedLoopback = totalBars / 5; for (int i = start; i < maxAllowedLoopback; i++) { // result = bar.Init( symbol, period, i // ); // if (!result) { break; } // double iPrice = bar.GetPrice(_type); // result = // iPrice > 0 && iPrice > price // ; if (result) { break; } } // if (!result) { bar.Clean(); } // return result; } // // Find Specific Price ... bool FindLowerPriceBar( XOHCL &bar, double price, ENUM_X_PRICE _type = X_PRICE_HIGH // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int totalBars = TotalBars(); result = IsValidSize(totalBars); if (!result) { return result; } // int start = Index(); int maxAllowedLoopback = totalBars / 5; for (int i = start; i < maxAllowedLoopback; i++) { // result = bar.Init( symbol, period, i // ); // if (!result) { break; } // double iPrice = bar.GetPrice(_type); // result = // iPrice > 0 && iPrice < price // ; if (result) { break; } } // if (!result) { bar.Clean(); } // return result; } // // Calculate up Price ... double GetUp() { // double result = 0; // if (!IsValid()) { return result; } // result = MathMax(open, close); // return result; } // // Calculate Down Price ... double GetDown() { // double result = 0; // if (!IsValid()) { return result; } // result = MathMin(open, close); // return result; } // // Calculate Bar Body ... double GetBody() { // double result = 0; // if (!IsValid()) { return result; } // result = GetUp() - GetDown(); // return result; } // // Calculate Bar Range ... double GetRange() { // double result = 0; // if (!IsValid()) { return result; } // result = high - low; // return result; } // // Calculate Bar Shadows ... double GetShadows() { // double result = 0; // if (!IsValid()) { return result; } // result = GetRange() - GetBody(); // return result; } // // Calculate Bar High Shadow ... double GetHighShadow() { // double result = 0; // if (!IsValid()) { return result; } // result = // high - GetUp() // ; // return result; } // // Calculate Bar Low Shadow ... double GetLowShadow() { // double result = 0; // if (!IsValid()) { return result; } // result = // GetDown() - low; // ; // return result; } // // Check Bar is Bullish ... bool IsBullish() { // bool result = false; // if (!IsValid()) { return result; } // result = open < close; // return result; } // // Check Bar is Bearish ... bool IsBearish() { // bool result = false; // if (!IsValid()) { return result; } // result = open > close; // return result; } // // Get Direction of Bar ... ENUM_X_DIRECTION GetDirection() { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // bool isBullish = IsBullish(); bool isBearish = IsBearish(); // result = isBullish && isBearish ? X_DIRECTION_ALL : !isBullish && !isBearish ? X_DIRECTION_NONE : isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Find Next Bar Time ... datetime NextAt() { // datetime result = NULL; // if (!IsValid()) { return result; } // int prSeconds = PeriodSeconds(period); // result = time + prSeconds; // return result; } // // Find Prev Bar Time ... datetime BeforeOn() { // datetime result = NULL; // if (!IsValid()) { return result; } // int prSeconds = PeriodSeconds(period); // result = time - prSeconds; // return result; } // // Calculate Last Bar Open Time in Smaller Period ... datetime GetLastBarTimeOfPeriod( ENUM_TIMEFRAMES smallerPeriod // ) { // datetime result = NULL; // if (!IsValid()) { return result; } // int sourceSeconds = PeriodSeconds(period); int destSeconds = PeriodSeconds(smallerPeriod); if (destSeconds >= sourceSeconds) { // result = time; return result; } // result = (datetime)((((int)time) + sourceSeconds) - destSeconds); // return result; } // // Calculate Close Time ... datetime GetCloseTime() { // datetime result = NULL; // if (!IsValid()) { return result; } // int seconds = PeriodSeconds(period); // result = (datetime)(((int)time) + seconds); // return result; } // bool BarAt( int index, XOHCL &bar // ) { // bool result = false; // bar.Clean(); // result = IsValid(); if (!result) { return result; } // if (index < 0) { index = 0; } // result = bar.Init( symbol, period, index // ); // return result; } // bool BarAt( datetime _time, XOHCL &bar // ) { // bool result = false; // bar.Clean(); // result = IsValid(); if (!result) { return result; } // _time = NormalizeTime(_time); // result = bar.Init( symbol, period, _time // ); // return result; } // bool BarIn( ENUM_TIMEFRAMES _period, XOHCL &bar // ) { // bool result = false; // bar.Clean(); // result = IsValid() && IsSpecifiedValid(_period); if (!result) { return result; } // int index = Index(_period); result = bar.Init( symbol, _period, index // ); // return result; } // // Find Current Bar Index on Chart ... int Index() { // int result = -1; // if (!IsValid()) { return result; } // result = iBarShift( symbol, period, time // ); // return result; } // int Index(datetime value) { // int result = -1; // value = NormalizeTime(value); // result = IsValid(); if (!result) { return result; } // result = iBarShift( symbol, period, value // ); // return result; } // int Index(ENUM_TIMEFRAMES value) { // int result = -1; // result = IsValid() && IsSpecifiedValid(value); if (!result) { return result; } // result = iBarShift( symbol, value, time // ); // return result; } // bool GetNextBar(XOHCL &bar) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int idx = Index(); result = idx > 0; if (!result) { return result; } // result = bar.Init( this.symbol, this.period, idx - 1 // ); // if (!result) { bar.Clean(); } // return result; } // bool GetPreviousBar(XOHCL &bar) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int idx = Index(); // result = bar.Init( this.symbol, this.period, idx + 1 // ); // if (!result) { bar.Clean(); } // return result; } // bool HasFiboPressure( ENUM_X_DIRECTION forDir, ENUM_X_FIBO_LEVELS level = X_FIBO_LEVEL_382 // ) { // bool result = false; // result = IsValid() && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsSpecifiedBullish(forDir); bool isBearish = IsSpecifiedBearish(forDir); // double fiboLevelValue = GetFibonacciLevel( high, low, level, forDir // ); // isBullish = isBullish && GetDown() > fiboLevelValue; isBearish = isBearish && GetUp() < fiboLevelValue; // result = isBullish || isBearish; // return result; } // bool IsRejected( double price, ENUM_X_DIRECTION forDir, bool forceType = false, bool forcePressure = false // ) { // bool result = false; // result = IsValid() && price > 0 && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsSpecifiedBullish(forDir) && low < price && GetDown() > price; // bool isBearish = IsSpecifiedBearish(forDir) && high > price && GetUp() < price; // if (forceType) { // isBullish = isBullish && IsBullish(); // isBearish = isBearish && IsBearish(); } // if (forcePressure) { // isBullish = isBullish && HasFiboPressure(forDir); // isBearish = isBearish && HasFiboPressure(forDir); } // result = isBullish || isBearish; // return result; } // bool IsBreaked( double price, ENUM_X_DIRECTION forDir, ENUM_X_FIBO_LEVELS fibLevel = X_FIBO_LEVEL_500, ENUM_X_BOUNDARY_PRICE boundaryType = X_BOUNDARY_PRICE_UP_DOWN // ) { // bool result = false; // result = IsValid() && price > 0 && HasDirection(forDir) && IsSpecifiedValid(boundaryType); if (!result) { return result; } // bool isUpDownPriceType = boundaryType == X_BOUNDARY_PRICE_UP_DOWN; // bool isBullish = IsBullish() && low < price && high > price && IsSpecifiedBullish(forDir); // bool isBearish = IsBearish() && low < price && high > price && IsSpecifiedBearish(forDir); // result = isBullish || isBearish; if (result) { // // Calculate Range ... double range = isUpDownPriceType ? GetBody() : GetRange(); // // Apply Edge Range ... double iReqRange = (range / 100) * (GetFiboLevelValue(fibLevel) * 100); // // Calculate Boundary Price ... double iBoundary = isUpDownPriceType ? isBullish ? GetUp() : GetDown() : isBullish ? high : low; // // Detect Breaked Value ... // double breakedPrice = isBullish ? (high - price) : (price - low); // result = breakedPrice >= iReqRange; } // return result; } // // Find Highest Bar Index ... int FindHighestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iHighest( symbol, period, mMode, mLength, Index()); // return result; } // // Find Highest ... double FindHighest( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindHighestIndex( mLength, mMode); if (idx <= -1) { return result; } // XOHCL iH; result = iH.Init( symbol, period, idx // ); if (!result) { return result; } // result = iH.GetPrice(mMode); // return result; } /** * Detect Highest of Specified Price type in Market ... * * @param index: souble, reference to hold detected Value Bar index ... * @param mLength: int, Specified Loopback Length ... * @param mPriceType: ENUM_X_PRICE, Specified Price type to Detect ... * * @return ( double ) */ double FindHighest( int &index, // Index ... int mLength, // Loopback ... ENUM_X_PRICE mPriceType // Price Type ... ) { // double result = EMPTY_VALUE; // // Prepare ... index = -1; // // Normalize ... mLength = NormalizeInt(mLength, 1); // // Validate ... bool has = IsValid() && IsXValid(mPriceType); if (!has) { return result; } // XOHCL iBar; int start = Index(); int end = start + mLength; double iValue = EMPTY_VALUE; for (int i = start; i < end; i++) { // iBar.Clean(); has = BarAt(i, iBar); if (!has) { continue; } // // Calculate Price ... iValue = iBar.GetPrice(mPriceType); // // Compare Price With Prev Detected ... has = !NotEmptyZero(result) ? true : iValue > result; if (has) { // index = i; result = iValue; } } // // Cleanup Resources ... iBar.Clean(); // return result; } // // Find Highest ... double FindHighestUp( int mLength // Loopback ... ) { // double result = 0; // if (!IsValid()) { return result; } // result = FindHighest(mLength, MODE_OPEN); result = MathMax(mLength, FindHighest(mLength, MODE_CLOSE)); // return result; } // // Find Lowest Bar Index ... int FindLowestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iLowest( symbol, period, mMode, mLength, Index()); // return result; } // // Find Lowest ... double FindLowest( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindLowestIndex( mLength, mMode); if (idx <= -1) { return result; } // XOHCL iL; result = iL.Init( symbol, period, idx // ); if (!result) { return result; } // result = iL.GetPrice(mMode); // return result; } /** * Detect Lowest of Specified Price type in Market ... * * @param index: souble, reference to hold detected Value Bar index ... * @param mLength: int, Specified Loopback Length ... * @param mPriceType: ENUM_X_PRICE, Specified Price type to Detect ... * * @return ( double ) */ double FindLowest( int &index, // Index ... int mLength, // Loopback ... ENUM_X_PRICE mPriceType // Price Type ... ) { // double result = EMPTY_VALUE; // // Prepare ... index = -1; // // Normalize ... mLength = NormalizeInt(mLength, 1); // // Validate ... bool has = IsValid() && IsXValid(mPriceType); if (!has) { return result; } // XOHCL iBar; int start = Index(); int end = start + mLength; double iValue = EMPTY_VALUE; for (int i = start; i < end; i++) { // iBar.Clean(); has = BarAt(i, iBar); if (!has) { continue; } // // Calculate Price ... iValue = iBar.GetPrice(mPriceType); // // Compare Price With Prev Detected ... has = !NotEmptyZero(result) ? true : iValue < result; if (has) { // index = i; result = iValue; } } // // Cleanup Resources ... iBar.Clean(); // return result; } // // Find Lowest ... double FindLowesttDown( int mLength // Loopback ... ) { // double result = 0; // if (!IsValid()) { return result; } // result = FindLowest(mLength, MODE_OPEN); result = MathMax(mLength, FindLowest(mLength, MODE_CLOSE)); // return result; } // // Swing Detection ... // int FindSwing( ENUM_X_SWING_TYPE type, int shoulders = 3 // ) { // int result = -1; // // Validate ... bool isValid = IsValid() && IsXValid(type); if (!isValid) { return result; } // // Find Next Swing ... result = FindXSwing( type, symbol, period, Index(), shoulders // ); // return result; } // int FindNextSwing( ENUM_X_SWING_TYPE type, int shoulders = 3 // ) { // int result = -1; // // Validate ... bool isValid = IsValid() && IsXValid(type); if (!isValid) { return result; } // // Find Next Swing ... result = FindXSwing( type, symbol, period, Index() + 1, shoulders // ); // return result; } // bool FindSwingBar( ENUM_X_SWING_TYPE type, XOHCL &swingBar, int shoulders = 3 // ) { // bool result = false; // // Prepare ... swingBar.Clean(); // // Validate ... result = IsValid() && IsXValid(type); if (!result) { return result; } // // Find Next Swing ... int idx = FindXSwing( type, symbol, period, Index(), shoulders // ); result = IsValidIndex(idx); if (!result) { return result; } // result = swingBar.Init( symbol, period, idx // ); // return result; } // bool FindNextSwingBar( ENUM_X_SWING_TYPE type, XOHCL &swingBar, int shoulders = 3 // ) { // bool result = false; // // Prepare ... swingBar.Clean(); // // Validate ... result = IsValid() && IsXValid(type); if (!result) { return result; } // // Find Next Swing ... int idx = FindXSwing( type, symbol, period, Index() + 1, shoulders // ); result = IsValidIndex(idx); if (!result) { return result; } // result = swingBar.Init( symbol, period, idx // ); // return result; } // // Same Checkers ... // bool IsSameAs(XOHCL &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameTime(item) && IsSameMarket(item); // return result; } // bool IsSameTime(XOHCL &item) { // bool result = false; // result = IsValid() && item.IsValid() && time == item.time; // return result; } // bool IsSameSymbol(XOHCL &item) { // bool result = false; // result = IsValid() && item.IsValid() && symbol == item.symbol; // return result; } // bool IsSamePeriod(XOHCL &item) { // bool result = false; // result = IsValid() && item.IsValid() && period == item.period; // return result; } // bool IsSameMarket(XOHCL &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameSymbol(item) && IsSamePeriod(item); // return result; } // // Other ... string GetTag(string prefix = "") { // string result = NULL; // result = (IsSpecifiedValid(prefix) ? prefix + "_" : "") + "XOHCL_" + symbol + "_" + ToXString(period) + "_" + ToFormatString(time); // return result; } // // Convert to String Representation ... string ToString() { // string result = ""; // result = GetTypeName(this) + "(O(" + ToXString(open) + "),H(" + ToXString(high) + "),C(" + ToXString(close) + "),L(" + ToXString(low) + "))"; // return result; } }; // // Models ... // // Model a Bar Remains Time ... struct XBarRemainsTime { // int days; int hours; int minutes; int seconds; // // Constructor ... XBarRemainsTime() { Clean(); } // // Always Calculate Current 0 Bar Timing ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int minuteSecoonds = 60; int hourSeconds = minuteSecoonds * 60; int daySeconds = 24 * hourSeconds; // int periodSeconds = PeriodSeconds( mPeriod); datetime startTime = GetBarTime( mSymbol, mPeriod, 0 // ); // int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); // int mWorkingSecondsDiff = secondsDiff; if (mWorkingSecondsDiff > daySeconds) { // days = mWorkingSecondsDiff / daySeconds; mWorkingSecondsDiff -= days * daySeconds; } if (mWorkingSecondsDiff > hourSeconds) { // hours = mWorkingSecondsDiff / hourSeconds; mWorkingSecondsDiff -= hours * hourSeconds; } if (mWorkingSecondsDiff > minuteSecoonds) { // minutes = mWorkingSecondsDiff / minuteSecoonds; mWorkingSecondsDiff -= minutes * minuteSecoonds; } seconds = mWorkingSecondsDiff; // result = true; // return result; } // // Tools ... // // Cleanup ... void Clean() { days = 0; hours = 0; minutes = 0; seconds = 0; // ZeroMemory(this); } // // To String Representation ... string ToString( string dayId = "d", string hourId = "h", string minuteId = "m", string secondId = "s", string idSeparator = ": ", string separator = ", ", bool ignoreZeroValues = true // ) { // string result = ""; // // Days ... if (!ignoreZeroValues || days > 0) { result += dayId + idSeparator + (string)days + separator; } // // Hours ... if (!ignoreZeroValues || hours > 0) { // string strHour = ToXString(hours); if (StringLen(strHour) == 1) { strHour = "0" + strHour; } // result += hourId + idSeparator + strHour + separator; } // // Minutes ... if (!ignoreZeroValues || minutes > 0) { // string strMinute = ToXString(minutes); if (StringLen(strMinute) == 1) { strMinute = "0" + strMinute; } // result += minuteId + idSeparator + strMinute + separator; } // // Seconds ... if (!ignoreZeroValues || seconds > 0) { // string strSec = ToXString(seconds); if (StringLen(strSec) == 1) { strSec = "0" + strSec; } // result += secondId + idSeparator + strSec; } // return result; } }; // // Tracking Times ... struct XTimeTracker { // // Props ... int xMonth; int xDayOfWeek; int xForWeekDay; int xDay; int xHour; int xMinute; // // Constructor ... XTimeTracker() { Clean(); } // // Tools ... // void Clean() { // xDay = -1; xHour = -1; xMonth = -1; xMinute = -1; xDayOfWeek = -1; xForWeekDay = -1; // ZeroMemory(this); } // // Detecting New Minute ... bool IsNewMinute() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.min != xMinute; if (result) { xMinute = timeStruct.min; } // return result; } // // Detecting New Houre ... bool IsNewHour() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.hour != xHour; if (result) { xHour = timeStruct.hour; } // return result; } // // Detecting New Day ... bool IsNewDay() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.day_of_year != xDay; if (result) { xDay = timeStruct.day_of_year; } // return result; } // // Detecting New Week ... bool IsNewWeek() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Week ... // Since Week Starts From Monday in Forex World ... // we Calculate Start of Week by 1-Monday ... result = xDayOfWeek == -1 && xForWeekDay == -1 ? true : timeStruct.day_of_week == 1 && timeStruct.day_of_year > xForWeekDay; // xForWeekDay = timeStruct.day_of_year; xDayOfWeek = timeStruct.day_of_week; // return result; } // // Detecting End Of Week ... bool IsWeekEnd() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check WeekEnd ... // Since Week Starts From Monday in Forex World ... // we Calculate End of Week by 5-Friday ... result = xDayOfWeek != -1 && timeStruct.day_of_week == 5 && timeStruct.hour == 23 && timeStruct.min == 59 && timeStruct.sec == 59; // return result; } // // Detecting New Month ... bool IsNewMonth() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.mon != xMonth; if (result) { xMonth = timeStruct.mon; } // return result; } }; // // Tracking Bars on Specified Environment ... struct XBarTracker { // string symbol; // Tracking Symbol ENUM_TIMEFRAMES period; // Tracking Time Frame // int lastTrackedBar; // Last Tracked Bar ... // bool waitsUntilNext; // Waits Until Next Bar ... // // Constructor ... XBarTracker() { Clean(); } // // Initializer ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // this.symbol = mSymbol; this.period = mPeriod; // this.lastTrackedBar = 0; // result = true; // return result; } // // Retrieve all Bars ... int CountBars() { // return iBars( symbol, period // ); } // // Check if it's New Bar ... bool IsNewBar() { // bool result = false; // int currentBars = CountBars(); // result = currentBars > lastTrackedBar; if (result) { lastTrackedBar = currentBars; } // return result; } // bool CanProcessBar() { // bool _isInTestMode = IsRunningOnTestMode(); // bool isNewBar = IsNewBar(); // bool result = _isInTestMode ? isNewBar : !waitsUntilNext ? true : isNewBar; if (result && waitsUntilNext) { waitsUntilNext = false; } // return result; } // void Waits() { this.waitsUntilNext = true; } // // Tools ... void Clean() { // symbol = NormalizeSymbol(NULL); period = NormalizePeriod(NULL); // ZeroMemory(this); } // bool GetBar( XOHCL &bar, int index = 0 // ) { // bool result = false; // result = bar.Init( symbol, period, index // ); // return result; } // bool GetBar( XOHCL &bar, datetime time = NULL // ) { // bool result = false; // NormalizeTime(time); // int barIndex = iBarShift( symbol, period, time, false // ); // result = barIndex >= 0; if (!result) { return result; } // result = bar.Init( symbol, period, barIndex // ); // return result; } // int Index(datetime time = NULL) { // int result = 0; // NormalizeTime(time); // result = iBarShift( symbol, period, time, false // ); // return result; } }; // // Extensions ... // // Extract Specific Range of Bars ... // using Start Bar Index ... int GetBars( XOHCL &bars[], // Hold Result string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame int from = 0, // Start Bar Index int count = 1 // Number of Bars ) { // int result = 0; // from = NormalizeInt(from); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int total = Bars( mSymbol, mPeriod // ); if (from > total - 2) { from = total - 2; } // if (count < 0) { count = 1; } // int start = from; int end = start + count; if (end > total - 1) { end = total - 1; } // Clean(bars); // for (int i = start; i < end; i++) { // XOHCL iBar; bool isValid = iBar.Init( mSymbol, mPeriod, i // ); // if (isValid) { // AddRef( iBar, bars // ); } } // result = ArraySize(bars); // return result; } // // Extract Specific Range of Bars ... // using Start Bar Time ... int GetBars( XOHCL &bars[], // Hold Result string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame datetime from = NULL, // Start Bar Time int count = 1 // Number of Bars ) { // from = NormalizeTime(from); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int barIndex = GetBarIndex( mSymbol, mPeriod, from // ); // return GetBars( bars, mSymbol, mPeriod, barIndex, count // ); } /** * Remove Specified Item from a Collection ... * * @param item: Specified Item ... * @param source: Specified Collection for Remove item from it ... * * @return ( bool ) */ bool Remove( XOHCL &item, XOHCL &source[] // ) { // bool result = false; // result = item.IsValid() && HasChild(source); if (!result) { return result; } // int idx = -1; result = FindIndex( idx, item, source // ); if (!result) { return result; } // result = ArrayRemove( source, idx, 1 // ); // return result; } /** * Remove Specified items from a Collection ... * * @param items: Specified Items to Remove ... * @param sources: Sepcified Collection for Removing items from it ... * * @return ( int ) */ int Removes( XOHCL &items[], XOHCL &sources[] // ) { // int result = 0; // bool has = HasChild(items) && HasChild(sources); if (!has) { return result; } // int idx = -1; has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // // Detect Item Index in Collection ... has = FindIndex( idx, items[i], sources // ); if (has) { // // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, 1 // ); // if (has) { // // Count Removed Items ... result++; } } } // return result; } /** * Find Specified Item index in a Collection ... * * @param index: int, reference to Hold Index if Exists ... * @param item: Specified item to Detect ... * @param source: Collection to Search for item ... * * @return ( bool ) */ bool FindIndex( int &index, XOHCL &item, XOHCL &source[] // ) { // bool result = false; // index = -1; // int count = ArraySize(source); result = item.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // bool isSame = item.IsSameAs(source[i]); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Add Specified Item to Specified Collection, if not Exists ... * * @param item: Item to Add ... * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) */ bool AddIfNotExists( XOHCL &item, XOHCL &sources[], int maxAllowed = 0 // ) { // bool result = false; // // Validate Args ... result = item.IsValid(); if (!result) { return result; } // // Check Item Exists or not ... int idx = -1; bool isExists = FindIndex( idx, item, sources // ); result = !isExists; if (!result) { return result; } // AddRef( item, sources // ); // // Handle Cleanup Collection // if Max Reached ... if (result && maxAllowed > 0) { // CleanupArray( sources, maxAllowed // ); } // return result; } /** * Get Oldest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetOldest( XOHCL &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XOHCL selected; for (int i = 0; i < count; i++) { // bool canSet = !selected.IsValid() ? true : selected.time > source[i].time; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Youngest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetYoungest( XOHCL &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XOHCL selected; for (int i = 0; i < count; i++) { // bool canSet = !selected.IsValid() ? true : selected.time < source[i].time; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Lowest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetLowest( XOHCL &source[], ENUM_X_PRICE _priceType = X_PRICE_LOW // ) { // int result = -1; // if (!IsXValid(_priceType)) { _priceType = X_PRICE_LOW; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XOHCL selected; double iPrice = EMPTY_VALUE; double selectedPrice = EMPTY_VALUE; for (int i = 0; i < count; i++) { // iPrice = source[i].GetPrice(_priceType); selectedPrice = selected.GetPrice(_priceType); // bool canSet = !selected.IsValid() ? true : selectedPrice > iPrice; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Highest Index of Specified Collection ... * * @param source: Specified Collection ... * @param _priceType: Specified Price type ... * * @return ( int ) */ int GetHighest( XOHCL &source[], ENUM_X_PRICE _priceType = X_PRICE_HIGH // ) { // int result = -1; // if (!IsXValid(_priceType)) { _priceType = X_PRICE_HIGH; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XOHCL selected; double iPrice = EMPTY_VALUE; double selectedPrice = EMPTY_VALUE; for (int i = 0; i < count; i++) { // iPrice = source[i].GetPrice(_priceType); selectedPrice = selected.GetPrice(_priceType); // bool canSet = !selected.IsValid() ? true : selectedPrice < iPrice; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Nearest Directional Bar ... * * @param bar: XOHCL, reference to Specified Start Bar ... * @param directionalBar: XOHCL, reference to hold Detected Bar ... * @param forDir: ENUM_X_DIRECTION, Specified Which Directional Bar looking for ... * @param loopback: int, Loopback Length ... * * @return ( bool ) */ bool GetDirectionalBar( XOHCL &bar, XOHCL &directionalBar, ENUM_X_DIRECTION forDir, int loopback = 1500 // ) { // bool result = false; // // Prepare ... directionalBar.Clean(); // // Normalize ... loopback = NormalizeInt(loopback, 1); // // Validate ... result = bar.IsValid() && HasDirection(forDir); if (!result) { return result; } // int start = bar.Index() + 1; int end = start + loopback; for (int i = start; i < end; i++) { // directionalBar.Clean(); result = bar.BarAt(i, directionalBar); result = result && directionalBar.GetDirection() == forDir; if (result) { break; } // directionalBar.Clean(); } // result = directionalBar.IsValid() && forDir == directionalBar.GetDirection(); // // Cleanup Resources ... if (!result) { directionalBar.Clean(); } // return result; } /** * Get Nearest Breaker Bar of Specified Bar's Price ... * * @param bar: XOHCL, reference to Specified Bar ... * @param breaker: XOHCL, reference to hold Detected Breaker Bar ... * @param priceType: ENUM_X_PRICE, which price type of Bar to Check to Break ... * @param breakType: ENUM_X_PRICE, which price of Breaker Bar must Breke price ... * @param breakDir: ENUM_X_DIRECTION, Specified Break Direction ... * @param loopback: int, Max Allowed Loopback to Detect Breaker Bar ... * * @return ( bool ) */ bool GetBreakerBar( XOHCL &bar, XOHCL &breaker, ENUM_X_PRICE priceType, ENUM_X_PRICE breakType, ENUM_X_DIRECTION breakDir, int loopback = 1500 // ) { // // PriceType: which Applied Price of Specified Bar must to Check for Break ... // // BreakType: which Applied Price of breakerBar must Break price ... // // BreakDir: // ----------- // Bullish: Price Must Break Applied Price from Down to Top ... // Bearish: Price must Break Applied Price from Top to Down ... // bool result = false; // // Prepare ... breaker.Clean(); // // Normalize ... loopback = NormalizeInt(loopback, 1); // // Validate ... result = bar.IsValid() && IsXValid(priceType) && IsXValid(breakType) && HasDirection(breakDir); if (!result) { return result; } // double iPrice = EMPTY_VALUE; bool isBullish = IsXBullish(breakDir); double price = bar.GetPrice(priceType); // int start = bar.Index(); int end = start + loopback; for (int i = start; i < end; i++) { // breaker.Clean(); iPrice = EMPTY_VALUE; // // Initialize Indexed Bar ... result = bar.BarAt(i, breaker); if (!result) { breaker.Clean(); break; } // // Check Breake ... iPrice = breaker.GetPrice(breakType); result = isBullish ? iPrice > price : iPrice < price; if (result) { break; } } // result = breaker.IsValid(); // // Cleanup Resources ... if (!result) { breaker.Clean(); } // return result; } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-pivot.analysis.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XPOILib // Description: All models related to POIs ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2025, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" /** * Model Specified Pivots Analysis ... **/ struct XPivotAnalysis { // // Props ... string name; // Name ... string symbol; // Symbol ... datetime time; // Time ... XPivot pivots[]; // Pivots ... ENUM_TIMEFRAMES period; // Period ... // // Linear Regression Parameters ... double peakSlope; double valeSlope; double peakIntercept; double valeIntercept; // // Analysed Results ... // // Directions ... ENUM_X_DIRECTION dir; // Trending Direction ... ENUM_X_DIRECTION peakDir; ENUM_X_DIRECTION valeDir; // // Predicted Values ... double peakTo; double valeTo; double peakFrom; double valeFrom; // // Time Analysis ... datetime toTime; datetime fromTime; // // Support and Resistances ... double minorSupport; double majorSupport; double minorResistance; double majorResistance; // // Constructor ... XPivotAnalysis() { Clean(); } // // Tools ... // // Cleaners ... /** * Cleanup Model ... */ void Clean() { // time = NULL; name = NULL; symbol = NULL; period = NULL; SpecifiedClean(pivots); // CleanAnalysis(); CleanLinearRegressionParameters(); // ZeroMemory(this); } /** * Clean Analysis Props ... */ void CleanAnalysis() { // toTime = NULL; fromTime = NULL; peakTo = EMPTY_VALUE; valeTo = EMPTY_VALUE; peakFrom = EMPTY_VALUE; valeFrom = EMPTY_VALUE; dir = X_DIRECTION_NONE; peakDir = X_DIRECTION_NONE; valeDir = X_DIRECTION_NONE; minorSupport = EMPTY_VALUE; majorSupport = EMPTY_VALUE; minorResistance = EMPTY_VALUE; majorResistance = EMPTY_VALUE; } /** * Clean Linear Regression Parameters ... */ void CleanLinearRegressionParameters() { // peakSlope = EMPTY_VALUE; valeSlope = EMPTY_VALUE; peakIntercept = EMPTY_VALUE; valeIntercept = EMPTY_VALUE; } // // Initializer / Actions (s) ... /** * Initialize Model ... * * @param _name: Name ... * @param _symbol: Symbol ... * @param _period: Period ... * @param _pivots: Provided Pivots ... * * @return ( bool ) */ bool Init( string _name, string _symbol, ENUM_TIMEFRAMES _period, XPivot &_pivots[] // ) { // bool result = false; // // Validate Args ... result = HasChild(_pivots) && IsSpecifiedValid(_name) && IsSpecifiedValid(_symbol) && IsSpecifiedValid(_period); if (!result) { // Clean(); return result; } // name = _name; symbol = _symbol; period = _period; Copy( _pivots, pivots // ); time = TimeCurrent(); // result = IsValid(); if (!result) { Clean(); } // // Do Calculations if Model is Valid ... if (result) { Update(); } // return result; } /** * Fully Update Analysis based on Pivots ... */ void Update() { // bool has = false; // // Prepare ... CleanAnalysis(); CleanLinearRegressionParameters(); // // Validate ... has = IsValid() && HasPivots(); if (!has) { return; } // // Calculate Linear Regression Parameters ... has = CalculateLinearRegressionParameters(); if (!has) { return; } // // Analyse ... has = Analyse(); if (!has) { return; } } /** * Fully Update Analysis based on Pivots ... * * @param _pivots: new Pivots Collection for Update ... */ void Update(XPivot &_pivots[]) { // bool has = IsValid() && HasChild(_pivots); if (!has) { return; } // SpecifiedClean(pivots); Copy( _pivots, pivots // ); // Update(); } /** * Re Analyse Pivots ... * * @return ( bool ) */ bool Analyse() { // bool result = false; // // Prepare ... CleanAnalysis(); // // Validate ... result = IsValid() && HasPivots() && HasLinearRegressionParameters(); if (!result) { return result; } // // Do Analyse ... // bool has = false; // // Specified To and From Time ... // // To Time ... int toIDX = GetYoungest(pivots); if (IsValidIndex(toIDX)) { // toTime = pivots[toIDX].time; toIDX = GetBarIndex( symbol, period, toTime // ); } // // From Time ... int fromIDX = GetOldest(pivots); if (IsValidIndex(fromIDX)) { // fromTime = pivots[fromIDX].time; fromIDX = GetBarIndex( symbol, period, fromTime // ); } // // Validate To From times ... result = IsValidIndex(toIDX) && IsValidIndex(fromIDX) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime); if (!result) { return result; } // // Predict Values ... // // Peaks ... // // Check Slope and Intercept Exists ... has = NotEmpty(peakSlope) && NotEmpty(peakIntercept); if (has) { // // To ... peakTo = PredictValue( peakSlope, peakIntercept, toIDX // ); // // From ... peakFrom = PredictValue( peakSlope, peakIntercept, fromIDX // ); } // // Vales ... // // Check Slope and Intercept Exists ... has = NotEmpty(valeSlope) && NotEmpty(valeIntercept); if (has) { // // To ... valeTo = PredictValue( valeSlope, valeIntercept, toIDX // ); // // From ... valeFrom = PredictValue( valeSlope, valeIntercept, fromIDX // ); } // // Check Directions ... // // Peak ... has = IsPeakAnalysed(); if (has) { // peakDir = peakFrom < peakTo ? X_DIRECTION_BULLISH : peakFrom > peakTo ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Vale ... has = IsValeAnalysed(); if (has) { // valeDir = valeFrom < valeTo ? X_DIRECTION_BULLISH : valeFrom > valeTo ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Check For Strong Type Trending ... has = IsPeakAnalysed() && IsValeAnalysed() && peakDir == valeDir; if (has) { dir = peakDir; } // // Calculate Support and Resistances ... // // Support ... ExtractSupport( minorSupport, majorSupport, pivots // ); // // Resistance ... ExtractResistances( minorResistance, majorResistance, pivots // ); // result = IsAnalysed(); // // Cleanup Resources ... // return result; } /** * Re Calculate Linear Regression Parameters ... * * @return ( bool ) */ bool CalculateLinearRegressionParameters() { // bool result = false; // // Prepare ... CleanLinearRegressionParameters(); // // Validate ... result = IsValid() && HasPivots(); if (!result) { return result; } // // Make a Copy of Pivots ... XPivot tmpPivots[]; Copy( pivots, tmpPivots // ); // // Sort Pivots ... Sort( tmpPivots, X_SORT_BY_DATE, X_DIRECTION_BEARISH // ); // // Do Calculations ... // double yData[]; double xData[]; bool has = false; // // Peaks ... // XPivot peaks[]; int peaksCount = ExtractPivots( peaks, tmpPivots, X_PIVOT_TYPE_PEAK // ); has = IsValidSize(peaksCount); if (has) { // // Extract X and Y axis Data ... ExtractPivotsData( xData, yData, peaks // ); // // Calculating Slope and Intercept ... has = ArraySize(xData) >= 2 && ArraySize(yData) >= 2; if (has) { // CalculateSlopeAndIntercept( peakSlope, peakIntercept, xData, yData // ); } } // // Vales ... // XPivot vales[]; int valesCount = ExtractPivots( vales, tmpPivots, X_PIVOT_TYPE_VALE // ); has = IsValidSize(valesCount); if (has) { // // Extract X and Y axis Data ... ExtractPivotsData( xData, yData, vales // ); // // Calculating Slope and Intercept ... has = ArraySize(xData) >= 2 && ArraySize(yData) >= 2; if (has) { // CalculateSlopeAndIntercept( valeSlope, valeIntercept, xData, yData // ); } } // // Validate Result ... result = IsValid() && HasLinearRegressionParameters(); // // Cleanup Resources ... SpecifiedClean(yData); SpecifiedClean(xData); SpecifiedClean(peaks); SpecifiedClean(vales); SpecifiedClean(tmpPivots); // return result; } // // Validator / Checker (s) ... /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = HasPivots() && IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period); // return result; } /** * Check Model has Pivots or not ... * * @return ( bool ) */ bool HasPivots() { // bool result = false; // result = HasChild(pivots); // return result; } /** * Check Model is Analysed or not ... * * @return ( bool ) */ bool IsAnalysed() { // bool result = false; // result = IsPeakAnalysed() || IsValeAnalysed(); // return result; } /** * Check Peak Analysed or not ... * * @return ( bool ) */ bool IsPeakAnalysed() { // bool result = false; // result = IsValid() && HasLinearRegressionParameters() && ( // NotEmpty(peakTo) && NotEmpty(peakFrom) && // HasDirection(peakDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // ); // return result; } /** * Check Vale Analysed or not ... * * @return ( bool ) */ bool IsValeAnalysed() { // bool result = false; // result = IsValid() && HasLinearRegressionParameters() && ( // NotEmpty(valeTo) && NotEmpty(valeFrom) && // HasDirection(valeDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // ); // return result; } /** * Check Models Linear Regression Parameters Calculated or not ... * * @return ( bool ) */ bool HasLinearRegressionParameters() { // bool result = false; // result = (NotEmpty(peakSlope) && NotEmpty(peakIntercept)) || (NotEmpty(valeSlope) || NotEmpty(valeIntercept)); // return result; } /** * Check Analysis Has Trend or not ... * * @return ( bool ) */ bool HasTrend() { // bool result = false; // result = IsAnalysed() && HasDirection(dir); // return result; } /** * Check Analysis Has Bullish Trend or not ... * * @return ( bool ) */ bool HasBullishTrend() { // bool result = false; // result = HasTrend() && IsSpecifiedBullish(dir); // return result; } /** * Check Analysis Has Bearish Trend or not ... * * @return ( bool ) */ bool HasBearishTrend() { // bool result = false; // result = HasTrend() && IsSpecifiedBearish(dir); // return result; } /** * Check Market Has Support ... * * @return ( bool ) */ bool HasSupport() { // bool result = false; // result = IsValid() && HasPivots() && IsAnalysed() && NotEmpty(minorSupport) && NotEmpty(majorSupport); // return result; } /** * Check Market Has Resistance ... * * @return ( bool ) */ bool HasResistance() { // bool result = false; // result = IsValid() && HasPivots() && IsAnalysed() && NotEmpty(minorResistance) && NotEmpty(majorResistance); // return result; } // // Pivots ... /** * Extract all Peaks from Exists Pivots ... * * @param dest: a Collection refrence to Hold Extracted Pivots ... * * @return ( int ) */ int ExtractPeaks(XPivot &dest[]) { // int result = -1; // // Prepare ... SpecifiedClean(dest); // // Do Extraction ... result = ExtractPivots( dest, pivots, X_PIVOT_TYPE_PEAK // ); // return result; } /** * Extract all Vales from Exists Pivots ... * * @param dest: a Collection refrence to Hold Extracted Pivots ... * * @return ( int ) */ int ExtractVales(XPivot &dest[]) { // int result = -1; // // Prepare ... SpecifiedClean(dest); // // Do Extraction ... result = ExtractPivots( dest, pivots, X_PIVOT_TYPE_VALE // ); // return result; } /** * Sort Pivots ... * * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... */ void SortPivots( ENUM_X_SORT_BY sortBy, ENUM_X_DIRECTION sortDir // ) { // // Validate ... bool has = IsValid() && HasPivots(); if (!has) { return; } // // Apply Sorting ... Sort( pivots, sortBy, sortDir // ); } // // Boxing Tools ... /** * Generate Support Box if Has Strong Supports ... * * @param box: a refrence XBoxZone to holds Generated result ... * * @return ( bool ) */ bool HasSupportBox(XBoxZone &box) { // bool result = false; // // Prepare ... box.Clean(); // // Validate ... result = IsValid() && IsAnalysed(); if (!result) { return result; } // box.to = toTime; box.symbol = symbol; box.period = period; box.from = fromTime; // box.upper = minorSupport; box.lower = majorSupport; box.dir = X_DIRECTION_BULLISH; box.type = GetTag() + "_Support"; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } /** * Generate Resistance Box if Has Strong Resistance ... * * @param box: a refrence XBoxZone to holds Generated result ... * * @return ( bool ) */ bool HasResistanceBox(XBoxZone &box) { // bool result = false; // // Prepare ... box.Clean(); // // Validate ... result = IsValid() && IsAnalysed(); if (!result) { return result; } // box.to = toTime; box.symbol = symbol; box.period = period; box.from = fromTime; // box.upper = majorResistance; box.lower = minorResistance; box.dir = X_DIRECTION_BEARISH; box.type = GetTag() + "_Resistance"; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } // // Detecting ... /** * Check Two Model is Same or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameMarketAs(item) && name == item.name && time == item.time; // return result; } /** * Check Two Model Has Same Symbol or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameSymbolAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && symbol == item.symbol; // return result; } /** * Check Two Model Has Same Period or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSamePeriodAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && period == item.period; // return result; } /** * Check Two Model Has Same Symbol/Period or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameMarketAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameSymbolAs(item) && IsSamePeriodAs(item); // return result; } // // Logging ... /** * Extract Specified Token of Struct ... * * @return ( string ) */ string GetTag() { return name + GetToken(this); } /** * Represent an String Unique Identifier for Chart Objects ... * * @return ( string ) */ string GetObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period); // return result; } /** * Represent an String Unique Identifier for Upper Trend Chart Objects ... * * @return ( string ) */ string GetUpperObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_UPPER"; // return result; } /** * Represent an String Unique Identifier for Lower Trend Chart Objects ... * * @return ( string ) */ string GetLowerObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_LOWER"; // return result; } /** * Represent an String Unique Identifier for Support Box Chart Objects ... * * @return ( string ) */ string GetSupportBoxObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_SUPPORT"; // return result; } /** * Represent an String Unique Identifier for Resistance BOX Chart Objects ... * * @return ( string ) */ string GetResistanceBoxObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_RESISTANCE"; // return result; } /** * Represent as String ... * * @param spacer: string, How to Represent Spaces ... * * @return ( string ) */ string GetMessage(string spacer = NULL) { // string result = ""; // // Normalize Spacer ... if (!IsSpecifiedValid(spacer)) { spacer = " "; } // // Validate ... if (!IsValid()) { return result; } // result = "==========================" + spacer + GetTag() + ":" + spacer + "==========================" + spacer + "Symbol: " + symbol + spacer + "Period: " + ToXString(period) + spacer + (!HasTrend() ? "" : "Direction: " + ToXString(dir) + spacer) + "Time: " + ToXString(time) + spacer; // return result; } // }; /** * a Model to Describe Specified Bar Pattern's Analysis ... **/ struct XPatternAnalysis { // // Props ... XOHCL bar; // Specified Bar ... XBoxZone ob; // OrderBlock if Exists ... XBoxZone fvg; // Fair Value Gap if Exists ... datetime time; // Analysis Time ... XOHCL flagSwing; // Flag Patterns Swing Bar if Exists ... XBoxZone support; // Bar's Support if Exists ... XBoxZone resistance; // Bar's Resistance if Exists ... ENUM_X_BAR_PATTERN patterns[]; // All Bars Exists Patterns ... ENUM_X_DIRECTION patternsDir[]; // Each Exists Patterns Directions ... // // Constructor ... XPatternAnalysis() { Clean(); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // ob.Clean(); bar.Clean(); fvg.Clean(); time = NULL; support.Clean(); XClean(patterns); flagSwing.Clean(); resistance.Clean(); XClean(patternsDir); // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = bar.IsValid() && IsXValid(time); // return result; } // // Pattern Actions ... /** * Count Directional Patterns ... * * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int Count( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Validate ... bool has = IsValid() && HasChild(patternsDir); if (!has) { return result; } // int count = ArraySize(patternsDir); if (!HasDirection(forDir)) { // result = count; return result; } // for (int i = 0; i < count; i++) { // has = forDir == patternsDir[i]; if (has) { result++; } } // return result; } // // Detectors ... bool IsHigh() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_HIGH); // return result; } bool IsLow() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_LOW); // return result; } bool IsSupport() { // bool result = false; // result = HasPattern( X_BAR_PATTERN_SUPPORT // ); // return result; } bool IsResistance() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_RESISTANCE); // return result; } bool IsMomentum( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_MOMENTUM, forDir // ); // return result; } bool IsEngulfed( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_ENGULFED, forDir // ); // return result; } bool IsTrueGaped( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_TRUE_GAPED, forDir // ); // return result; } bool IsPinned( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_PINNED, forDir // ); // return result; } bool IsStar( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_STAR, forDir // ); // return result; } bool IsPiercing( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_PIERCING, forDir // ); // return result; } bool IsRising( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_RISING, forDir // ); // return result; } bool IsFlag( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_FLAG, forDir // ); // return result; } bool IsSignalKey( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_SIGNALKEY, forDir // ); // return result; } bool IsOB( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_OB, forDir // ); // return result; } bool IsFVG( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_FVG, forDir // ); // return result; } // // Getters ... bool GetLow( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_LOW; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BULLISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetHigh( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_HIGH; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BEARISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetSupport( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_SUPPORT; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BULLISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetResistance( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_RESISTANCE; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BEARISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetOB( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_OB; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetFVG( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_FVG; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetMomentum( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_MOMENTUM; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetEngulfed( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_ENGULFED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetPinned( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_PINNED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetTrueGaped( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_TRUE_GAPED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetStar( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_STAR; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetFlag( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_FLAG; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetRising( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_RISING; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetPiercing( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_PIERCING; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetSignalKey( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_SIGNALKEY; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } // // Common Tools ... /** * Add Specified Patterns to Model ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... */ void AddPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir // ) { // bool has = IsXValid(pattern) && HasDirection(patternDir); if (!has) { return; } // Add( pattern, patterns // ); // Add( patternDir, patternsDir // ); } /** * Check Model Has Specified Pattern or not ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * * @return ( bool ) */ bool HasPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // result = Contains( pattern, patterns // ); if (!result) { return result; } // if (HasDirection(forDir)) { // int idx = FindIndex( pattern, patterns // ); result = IsValidIndex(idx) && forDir == patternsDir[idx]; } // return result; } /** * Get Specified Pattern if Exists ... * * @param _bar: XOHCL, Patterns Bar ... * @param _pivot: XPivot, Patterns Pivot ... * @param _zone: XBoxZone, Patterns Box ... * @param _pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param _patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * @param _peakPriceType: ENUM_X_PRICE, Specified Peak Price Type ... * @param _valePriceType: ENUM_X_PRICE, Specified Vale Price Type ... * @param _toTime: datetime, Specified Time to Update Pivot and Zones ... * * @return ( bool ) */ bool GetPattern( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_BAR_PATTERN _pattern, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // bool result = false; // // Prepare ... _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Normalize ... if (!IsXValid(_peakPriceType)) { _peakPriceType = X_PRICE_HIGH; } if (!IsXValid(_valePriceType)) { _valePriceType = X_PRICE_LOW; } _toTime = NormalizeTime(_toTime); // // Validate ... result = IsValid() && HasChild(patterns) && IsXValid(_peakPriceType) && IsXValid(_valePriceType) && HasPattern(_pattern, _patternDir); if (!result) { return result; } // // Find Pattern Index ... int index = FindIndex(_pattern, patterns); result = IsValidIndex(index); if (!result) { return result; } // // Fill Common Patterns Data ... _bar = bar; result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); result = result && ToBox( _bar, _zone, _patternDir, _pattern, _peakPriceType, _valePriceType // ); if (result) { _zone.to = _toTime; } // // Use Custom Data if Pattern Staisfied ... if (result) { // // OB ... if (_pattern == X_BAR_PATTERN_OB) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = ob.IsValid() && ob.dir == _patternDir; if (result) { // _zone = ob; result = _zone.FromBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // FVG ... else if (_pattern == X_BAR_PATTERN_FVG) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = fvg.IsValid() && fvg.dir == _patternDir; if (result) { // _zone = fvg; result = _zone.FromBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // Support ... else if (_pattern == X_BAR_PATTERN_SUPPORT) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = support.IsValid(); if (result) { // _zone = support; result = _zone.AtBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // Resistance ... else if (_pattern == X_BAR_PATTERN_RESISTANCE) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = resistance.IsValid(); if (result) { // _zone = resistance; result = _zone.AtBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } } // // Cleanup Resources ... if (!result) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); } // return result; } /** * Extract All Exists Patterns Pivots ... * * @param dest: XPivot, collection reference to holds Extracted Patterns ... * @param forDir: ENUM_X_DIRECTION, Specified Direction of Extractions ... * * @return ( int ) */ int GetPatterns( XPivot &dest[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = IsValid() && HasChild(patterns); if (!has) { return result; } // // Do ... XOHCL iBar; XPivot iPivot; XBoxZone iZone; int count = ArraySize(patterns); for (int i = 0; i < count; i++) { // has = GetPattern(iBar, iPivot, iZone, patterns[i], forDir); if (has) { AddIfNotExists(iPivot, dest); } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iZone.Clean(); iPivot.Clean(); // return result; } /** * Extract All Exists Patterns Pivots ... * * @param dest: XBoxZone, collection reference to holds Extracted Patterns ... * @param forDir: ENUM_X_DIRECTION, Specified Direction of Extractions ... * * @return ( int ) */ int GetPatterns( XBoxZone &dest[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = IsValid() && HasChild(patterns); if (!has) { return result; } // // Do ... XOHCL iBar; XPivot iPivot; XBoxZone iZone; int count = ArraySize(patterns); for (int i = 0; i < count; i++) { // has = GetPattern(iBar, iPivot, iZone, patterns[i], forDir); if (has) { AddIfNotExists(iZone, dest); } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iZone.Clean(); iPivot.Clean(); // return result; } /** * Extract All Exists Patterns Pivots ... * * @param dest: XPivot, collection reference to holds Extracted Patterns ... * @param zones: XBoxZone, collection reference to holds Extracted Patterns ... * @param forDir: ENUM_X_DIRECTION, Specified Direction of Extractions ... * * @return ( int ) */ int GetPatterns( XPivot &dest[], XBoxZone &zones[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); XClean(zones); // // Validate ... bool has = IsValid() && HasChild(patterns); if (!has) { return result; } // // Do ... XOHCL iBar; XPivot iPivot; XBoxZone iZone; int count = ArraySize(patterns); for (int i = 0; i < count; i++) { // has = GetPattern(iBar, iPivot, iZone, patterns[i], forDir); if (has) { // AddIfNotExists(iPivot, dest); AddIfNotExists(iZone, zones); } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iZone.Clean(); iPivot.Clean(); // return result; } // }; struct XPatternAnalysisConfig { // // Props ... // // PV ... int pvValidationLength; ENUM_X_PRICE peakPriceType; ENUM_X_PRICE valePriceType; // // Momentum ... int momentumBarValidationLength; double momentumBarApprovedMultiplier; // // TrueGap ... double trueGapApprovedStrength; // // Pin ... double pinBarShadowApprovedMultiplier; double pinBarRangeMultiplier; bool pinBarForceDirection; // // Flag ... int flagPatternPullbackLength; // // FVG ... bool fvgForceType; // // OB ... bool obForceTwoBar; // // Support and Resistance ... int supportAndResistanceValidationLength; int supportAndResistanceLoopbackLength; // ENUM_X_DIRECTION allowedDirs[]; ENUM_X_BAR_PATTERN allowedPatterns[]; // // Constructor ... XPatternAnalysisConfig() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // // PV ... pvValidationLength = 0; peakPriceType = X_PRICE_NONE; valePriceType = X_PRICE_NONE; // // Momentum ... momentumBarValidationLength = 0; momentumBarApprovedMultiplier = 0; // // TrueGap ... trueGapApprovedStrength = 0; // // Pin ... pinBarShadowApprovedMultiplier = 0; pinBarRangeMultiplier = 0; pinBarForceDirection = false; // // Flag ... flagPatternPullbackLength = 0; // // FVG ... fvgForceType = false; // // OB ... obForceTwoBar = false; // // Support and Resistance ... supportAndResistanceValidationLength = 0; supportAndResistanceLoopbackLength = 0; // XClean(allowedDirs); XClean(allowedPatterns); // ZeroMemory(this); } /** * Default Configurations ... */ void Default() { // // PV ... pvValidationLength = 5; peakPriceType = X_PRICE_HIGH; valePriceType = X_PRICE_LOW; // // Momentum ... momentumBarValidationLength = 3; momentumBarApprovedMultiplier = 3; // // TrueGap ... trueGapApprovedStrength = 1; // // Pin ... pinBarShadowApprovedMultiplier = 3; pinBarRangeMultiplier = 4; pinBarForceDirection = false; // // Flag ... flagPatternPullbackLength = 3; // // FVG ... fvgForceType = false; // // OB ... obForceTwoBar = false; // // Support and Resistance ... supportAndResistanceValidationLength = 21; supportAndResistanceLoopbackLength = 50; } // // Permissions ... /** * Check Specified Patterns Detection is Allowed or not ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern to Detect ... * @param patternDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... * * @return ( bool ) */ bool CanDetect( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE // ) { // bool result = false; // // Validate Pattern and // Check Pattern Exists ... result = IsXValid(pattern) && HasChild(allowedPatterns) && Contains(pattern, allowedPatterns); if (!result) { return result; } // // Now Check Direction ... int index = FindIndex(pattern, allowedPatterns); result = IsValidIndex(index) && HasChild(allowedDirs) && (!HasDirection(patternDir) ? !HasDirection(allowedDirs[index]) : (!HasDirection(allowedDirs[index]) || patternDir == allowedDirs[index])); // return result; } // // Collection Manipulations ... /** * Remove all Allowed Patterns and Directions ... */ void CleanPatterns() { // XClean(allowedDirs); XClean(allowedPatterns); } /** * Full Detect Patterns ... * * @param forDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... */ void FullPattern( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int count = GetAllBarPatters(allowedPatterns); for (int i = 0; i < count; i++) { // Add( forDir, allowedDirs // ); } } /** * Add Specified Pattern to Detecte ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern to Detect ... * @param patternDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... */ void AddPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE // ) { // bool has = IsXValid(pattern); if (!has) { return; } // Add( pattern, allowedPatterns // ); // Add( patternDir, allowedDirs // ); } // }; // // Anaysis Draw Config Models ... struct XPivotAnalysisDrawConfig { // // Props ... // // Drawing Flags ... bool drawSupport; bool drawResistance; // bool drawPeakTrend; bool drawValeTrend; bool rayLeftTrends; bool rayRightTrends; // bool drawPivots; // // Drawing Configs ... XPOIDrawConfig drawConfig; // // Constructor ... XPivotAnalysisDrawConfig() { Clean(); } // // Tools ... /** * This function fulfills the will of the developer */ void Clean() { // // Drawing Flags ... // drawPivots = false; drawSupport = false; drawPeakTrend = false; drawValeTrend = false; rayLeftTrends = false; rayRightTrends = false; drawResistance = false; // // Drawing Configs ... drawConfig.Clean(); // ZeroMemory(this); } /** * Default Configurations ... */ void Default() { // // Drawing Flags ... // drawPivots = false; drawSupport = true; drawPeakTrend = false; drawValeTrend = false; rayLeftTrends = true; rayRightTrends = true; drawResistance = true; // // Drawing Configs ... drawConfig.Default(); } /** * No Draw Abilioty ... */ void Off() { // drawPivots = false; drawSupport = false; drawPeakTrend = false; drawValeTrend = false; drawResistance = false; } /** * Full Draw Abilioty ... */ void Full() { // drawPivots = true; drawSupport = true; drawPeakTrend = true; drawValeTrend = true; drawResistance = true; } // }; struct XPatternAnalysisDrawConfig { // // Props ... // // Patterns ... // ENUM_X_BAR_PATTERN allowedDraws[]; // Allowed Draw Patterns ENUM_X_BAR_PATTERN allowedDrawZones[]; // Allowed Draw Pattern Zones ENUM_X_BAR_PATTERN allowedDrawPivots[]; // Allowed Draw Pattern Pivots // XPOIDrawConfig drawConfig; // // Constructor ... XPatternAnalysisDrawConfig() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // // Drawing Configs ... drawConfig.Clean(); // XClean(allowedDraws); XClean(allowedDrawZones); XClean(allowedDrawPivots); } /** * Default Drawing Config ... */ void Default() { // // Drawing Configs ... drawConfig.Default(); // Full(); // // Remove Unused From Zones ... Remove(X_BAR_PATTERN_PINNED, allowedDrawZones); Remove(X_BAR_PATTERN_MOMENTUM, allowedDrawZones); Remove(X_BAR_PATTERN_ENGULFED, allowedDrawZones); Remove(X_BAR_PATTERN_TRUE_GAPED, allowedDrawZones); // // Remove Unused From Pivots ... Remove(X_BAR_PATTERN_OB, allowedDrawPivots); Remove(X_BAR_PATTERN_FVG, allowedDrawPivots); Remove(X_BAR_PATTERN_SUPPORT, allowedDrawPivots); Remove(X_BAR_PATTERN_RESISTANCE, allowedDrawPivots); } /** * No Draw Abilioty ... */ void Off() { // XClean(allowedDraws); XClean(allowedDrawZones); XClean(allowedDrawPivots); } /** * Full Draw Abilioty ... */ void Full() { // GetAllBarPatters(allowedDraws); GetAllBarPatters(allowedDrawZones); GetAllBarPatters(allowedDrawPivots); } // // Checkers ... /** * Check Can Draw Specified Pattern ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDraw(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = HasChild(allowedDraws) && Contains(pattern, allowedDraws); // return result; } /** * Check Can Draw Specified Pattern's Zone ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDrawZone(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = CanDraw(pattern) && HasChild(allowedDrawZones) && Contains(pattern, allowedDrawZones); // return result; } /** * Check Can Draw Specified Pattern's Pivot ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDrawPivot(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = CanDraw(pattern) && HasChild(allowedDrawPivots) && Contains(pattern, allowedDrawPivots); // return result; } }; // // Extensions ... bool FindByTime( int &index, datetime time, XPatternAnalysis &source[] // ) { // bool result = false; // // Prepare ... index = -1; // // Validate ... result = IsXValid(time) && HasChild(source); if (!result) { return result; } // // Do ... int count = ArraySize(source); for (int i = 0; i < count; i++) { // result = source[i].bar.time == time; if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-poi.extensions.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XPOILib // Description: All models related to POIs ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright `023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Libraries/x-saherelm.x-ohcl.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" // // Extensions ... //+------------------------------------------------------------------+ //| Oldest Detection | //+------------------------------------------------------------------+ /** * Get Oldest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetOldest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = !selected.IsValid() ? true : selected.from > source[i].from; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Oldest Index of Specified Collection ... * * @param source: Specified Collection ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int GetOldestByDir( XBoxZone &source[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = (!HasDirection(forDir) ? true : forDir == source[i].dir) && (!selected.IsValid() ? true : selected.from > source[i].from); if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Oldest Index of Specified Collection ... * * @param bar: XOHCL, Specified Bar ... * @param source: Specified Collection ... * * @return ( int ) */ int GetOldestByBar( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]); if (!isBoxValidForBar) { continue; } // bool canSet = !selected.IsValid() ? true : selected.from > source[i].from; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Oldest Index of Specified Collection ... * * @param source: Specified Collection ... * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetOldest( XPivot &source[], ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // int result = -1; // // Validate ... if (!HasChild(source)) { return result; } // bool has = false; XPivot iPoint; int count = ArraySize(source); for (int i = 0; i < count; i++) { // // Passed Type ... has = !IsXValid(type) ? true : type == source[i].type; // // Check Can Assign ... has = has && (!iPoint.IsValid() || (iPoint.IsValid() && source[i].GetAge() > iPoint.GetAge())); if (has) { // result = i; iPoint = source[i]; } } // // Validate Result ... has = iPoint.IsValid() && IsValidIndex(result); if (!has) { // result = -1; iPoint.Clean(); return result; } // iPoint.Clean(); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Youngest Detection | //+------------------------------------------------------------------+ /** * Get Youngest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetYoungest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = !selected.IsValid() ? true : selected.from < source[i].from; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Youngest Index of Specified Collection ... * * @param source: Specified Collection ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int GetYoungestByDir( XBoxZone &source[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = (!HasDirection(forDir) ? true : forDir == source[i].dir) && (!selected.IsValid() ? true : selected.from < source[i].from); if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Youngest Index of Specified Collection ... * * @param bar: XOHCL, Specified Bar ... * @param source: Specified Collection ... * * @return ( int ) */ int GetYoungestByBar( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]); if (!isBoxValidForBar) { continue; } // bool canSet = !selected.IsValid() ? true : selected.from < source[i].from; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Youngest Index of Specified Collection ... * * @param source: Specified Collection ... * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetYoungest( XPivot &source[], ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // int result = -1; // // Validate ... if (!HasChild(source)) { return result; } // bool has = false; XPivot iPoint; int count = ArraySize(source); for (int i = 0; i < count; i++) { // // Passed Type ... has = !IsXValid(type) ? true : type == source[i].type; // // Check Can Assign ... has = has && (!iPoint.IsValid() || (iPoint.IsValid() && source[i].GetAge() < iPoint.GetAge())); if (has) { // result = i; iPoint = source[i]; } } // // Validate Result ... has = iPoint.IsValid() && IsValidIndex(result); if (!has) { // result = -1; iPoint.Clean(); return result; } // iPoint.Clean(); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Highest Detection | //+------------------------------------------------------------------+ /** * Get Highest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetHighest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = !selected.IsValid() ? true : selected.upper < source[i].upper; if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Highest Index of Specified Collection ... * * @param source: Specified Collection ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int GetHighestByDir( XBoxZone &source[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // bool canSet = (!HasDirection(forDir) ? true : forDir == source[i].dir) && (!selected.IsValid() ? true : selected.upper < source[i].upper); if (canSet) { // result = i; selected = source[i]; } } // selected.Clean(); // return result; } /** * Get Highest Index of Specified Collection ... * * @param bar: XOHCL, Specified Bar ... * @param source: Specified Collection ... * * @return ( int ) */ int GetHighestByBar( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.upper < iBox.upper; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Highest Bar Price Index of Specified Collection ... * * @param source: reference collection, Provides Data Source ... * * @return ( int ) */ int GetHighestBarPrice( XOHCL &source[], ENUM_X_PRICE priceType // ) { // int result = -1; // // Validate ... bool has = HasChild(source) && IsXValid(priceType); if (!has) { return result; } // double price = EMPTY_VALUE; double selected = EMPTY_VALUE; int count = ArraySize(source); for (int i = 0; i < count; i++) { // price = source[i].GetPrice(priceType); has = !NotEmptyZero(selected) ? true : price > selected; if (has) { // result = i; selected = price; } } // return result; } /** * Get Highest Index of Specified Collection ... * * @param source: Specified Collection ... * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetHighest( XPivot &source[], ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // int result = -1; // // Validate ... if (!HasChild(source)) { return result; } // bool has = false; XPivot iPoint; int count = ArraySize(source); for (int i = 0; i < count; i++) { // // Passed Type ... has = !IsXValid(type) ? true : type == source[i].type; // // Check Can Assign ... has = has && (!iPoint.IsValid() || (iPoint.IsValid() && source[i].value > iPoint.value)); if (has) { // result = i; iPoint = source[i]; } } // // Validate Result ... has = iPoint.IsValid() && IsValidIndex(result); if (!has) { // result = -1; iPoint.Clean(); return result; } // iPoint.Clean(); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Loest Detection | //+------------------------------------------------------------------+ /** * Get Lowest Index of Specified Collection ... * * @param source: Specified Collection ... * * @return ( int ) */ int GetLowest( XBoxZone &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = !selected.IsValid() ? true : selected.lower > iBox.lower; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Lowest Index of Specified Collection ... * * @param source: Specified Collection ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int GetLowestByDir( XBoxZone &source[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool canSet = (!HasDirection(forDir) ? true : forDir == source[i].dir) && (!selected.IsValid() ? true : selected.lower > iBox.lower); if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Lowest Index of Specified Collection ... * * @param bar: XOHCL, Specified Bar ... * @param source: Specified Collection ... * * @return ( int ) */ int GetLowestByBar( XOHCL &bar, XBoxZone &source[] // ) { // int result = -1; // if (!bar.IsValid()) { return result; } // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone selected; for (int i = 0; i < count; i++) { // XBoxZone iBox = source[i]; // bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox); if (!isBoxValidForBar) { // iBox.Clean(); // continue; } // bool canSet = !selected.IsValid() ? true : selected.lower > iBox.lower; if (canSet) { // result = i; selected = iBox; } // iBox.Clean(); } // selected.Clean(); // return result; } /** * Get Lowest Bar Price Index of Specified Collection ... * * @param source: reference collection, Provides Data Source ... * * @return ( int ) */ int GetLowestBarPrice( XOHCL &source[], ENUM_X_PRICE priceType // ) { // int result = -1; // // Validate ... bool has = HasChild(source) && IsXValid(priceType); if (!has) { return result; } // double price = EMPTY_VALUE; double selected = EMPTY_VALUE; int count = ArraySize(source); for (int i = 0; i < count; i++) { // price = source[i].GetPrice(priceType); has = !NotEmptyZero(selected) ? true : price < selected; if (has) { // result = i; selected = price; } } // return result; } /** * Get Lowest Index of Specified Collection ... * * @param source: Specified Collection ... * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetLowest( XPivot &items[], ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // int result = -1; // // Validate ... if (!HasChild(items)) { return result; } // bool has = false; XPivot iPoint; int count = ArraySize(items); for (int i = 0; i < count; i++) { // // Passed Type ... has = !IsXValid(type) ? true : type == items[i].type; // // Check Can Assign ... has = has && (!iPoint.IsValid() || (iPoint.IsValid() && items[i].value < iPoint.value)); if (has) { // result = i; iPoint = items[i]; } } // // Validate Result ... has = iPoint.IsValid() && IsValidIndex(result); if (!has) { // result = -1; iPoint.Clean(); return result; } // iPoint.Clean(); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Box | //+------------------------------------------------------------------+ /** * Extract all items which appears Before Specified Time ... * * @param _time: Specified Time ... * @param dest: refrence collection to hold result ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetBeforeItems( datetime _time, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... int count = ArraySize(source); bool has = HasChild(source) && IsSpecifiedValid(_time); if (!has) { return result; } // // Loop through Items ... for (int i = 0; i < count; i++) { // has = source[i].from < _time; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all items which appears After Specified Time ... * * @param _time: Specified Time ... * @param dest: refrence collection to hold result ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetAfterItems( datetime _time, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... int count = ArraySize(source); bool has = HasChild(source) && IsSpecifiedValid(_time); if (!has) { return result; } // // Loop through Items ... for (int i = 0; i < count; i++) { // has = source[i].from > _time; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all items which appears Above Specified Value ... * * @param _value: Specified Value ... * @param dest: refrence collection to hold result ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetAboveItems( double _value, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... int count = ArraySize(source); bool has = HasChild(source) && NotEmptyZero(_value); if (!has) { return result; } // // Loop through Items ... for (int i = 0; i < count; i++) { // has = source[i].lower > _value; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all items which appears Below Specified Value ... * * @param _value: Specified Value ... * @param dest: refrence collection to hold result ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetBelowItems( double _value, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... int count = ArraySize(source); bool has = HasChild(source) && NotEmptyZero(_value); if (!has) { return result; } // // Loop through Items ... for (int i = 0; i < count; i++) { // has = source[i].upper < _value; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Get Oldest Item Index of all items which appears Before Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetOldestBefore( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBeforeItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetOldest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Oldest Item Index of all items which appears After Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetOldestAfter( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAfterItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetOldest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Oldest Item Index of all items which appears Above Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetOldestAbove( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAboveItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetOldest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Oldest Item Index of all items which appears Below Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetOldestBelow( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBelowItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetOldest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Youngest Item Index of all items which appears Before Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetYoungestBefore( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBeforeItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetYoungest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Youngest Item Index of all items which appears After Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetYoungestAfter( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAfterItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetYoungest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Youngest Item Index of all items which appears Above Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetYoungestAbove( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAboveItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetYoungest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Youngest Item Index of all items which appears Below Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetYoungestBelow( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBelowItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetYoungest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Highest Item Index of all items which appears Before Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetHighestBefore( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBeforeItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetHighest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Highest Item Index of all items which appears After Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetHighestAfter( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAfterItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetHighest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Highest Item Index of all items which appears Above Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetHighestAbove( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAboveItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetHighest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Highest Item Index of all items which appears Below Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetHighestBelow( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBelowItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetHighest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Lowest Item Index of all items which appears Before Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetLowestBefore( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBeforeItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetLowest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Lowest Item Index of all items which appears After Specified Value ... * * @param _time: Specified Time ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetLowestAfter( datetime _time, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAfterItems( _time, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetLowest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Lowest Item Index of all items which appears Above Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetLowestAbove( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetAboveItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetLowest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Get Lowest Item Index of all items which appears Below Specified Value ... * * @param _value: Specified Value ... * @param source: refrence collection to provides data source ... * * @return ( int ) */ int GetLowestBelow( double _value, XBoxZone &source[] // ) { // int result = -1; // XBoxZone tmps[]; int tmpsCount = GetBelowItems( _value, tmps, // Dest ... source // Source ... ); bool has = IsValidSize(tmpsCount); int idx = GetLowest(tmps); has = has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); SpecifiedClean(tmps); // return result; } /** * Validate an Item Strength ... * * @param item: Specified Item for Validating ... * @param minAllowedStrength: int, Minimum required Strength in Point ... * * @return ( bool ) */ bool ValidateStrength( XBoxZone &item, int minAllowedStrength = 0 // ) { // bool result = false; // // Normalize ... minAllowedStrength = NormalizeInt(minAllowedStrength, 0); // // Validate ... result = item.IsValid(); if (!result) { return result; } // // If doent provide Specified Strength Validate Zone ... result = minAllowedStrength <= 0; if (result) { return result; } // double points = GetPoints(item.symbol); double requiredStrength = minAllowedStrength * points; double itemStrength = item.upper - item.lower; // result = itemStrength > 0 && requiredStrength > 0 && itemStrength > requiredStrength; // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Sort | //+------------------------------------------------------------------+ /** * Allowed Sort Param ... **/ enum ENUM_X_SORT_BY { X_SORT_BY_NONE = 0, // None X_SORT_BY_DATE = 1, // by Date X_SORT_BY_VALUE = 2, // by Date }; /** * Check Specified Sort By Validation ... * * @param value: ENUM_X_SORT_BY, value to Validate ... * * @return ( bool ) */ bool IsXValid(ENUM_X_SORT_BY value) { return value != X_SORT_BY_NONE; } /** * Select Specified Index of a Collection by Sort Params ... * * @param source: Collection for Search ... * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... * * @return ( int ) */ template int SelectItemForSorting( T &source[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH // ) { // int result = -1; // // Validate ... if (!HasChild(source) || !IsXValid(sortBy) || !HasDirection(sortDir)) { return result; } // // Sort By Date ... if (sortBy == X_SORT_BY_DATE) { // // Select Based on Sorting Direction ... // // form Oldest to Youngest ... if (sortDir == X_DIRECTION_BULLISH) { result = GetOldest(source); } // // form Youngest to Oldest ... else if (sortDir == X_DIRECTION_BEARISH) { result = GetYoungest(source); } // // Not Valid ... else { result = -1; } } // // Sort By Value ... else if (sortBy == X_SORT_BY_VALUE) { // // form Lowst to Highest ... if (sortDir == X_DIRECTION_BULLISH) { result = GetLowest(source); } // // form Highest to Lowest ... else if (sortDir == X_DIRECTION_BEARISH) { result = GetHighest(source); } // // Not Valid ... else { result = -1; } } // // Not Valid ... else { result = -1; } // return result; } /** * Select Specified Index of a Collection by Sort Params ... * * @param source: Collection for Search ... * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... * * @return ( int ) */ int SelectBarForSorting( XOHCL &source[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH, ENUM_X_PRICE priceType = X_PRICE_NONE // ) { // int result = -1; // // Validate ... if (!HasChild(source) || !IsXValid(sortBy) || !HasDirection(sortDir)) { return result; } // // Sort By Date ... if (sortBy == X_SORT_BY_DATE) { // // Select Based on Sorting Direction ... // // form Oldest to Youngest ... if (sortDir == X_DIRECTION_BULLISH) { result = GetOldest(source); } // // form Youngest to Oldest ... else if (sortDir == X_DIRECTION_BEARISH) { result = GetYoungest(source); } // // Not Valid ... else { result = -1; } } // // Sort By Value ... else if (sortBy == X_SORT_BY_VALUE) { // // form Lowst to Highest ... if (sortDir == X_DIRECTION_BULLISH) { result = GetLowest(source, priceType); } // // form Highest to Lowest ... else if (sortDir == X_DIRECTION_BEARISH) { result = GetHighest(source, priceType); } // // Not Valid ... else { result = -1; } } // // Not Valid ... else { result = -1; } // return result; } /** * Apply Sort on Specified Collection ... * * @param source: Collection Reference to Sort ... * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... * @param maxAllowed: int, Max Allowed Collection Size ... */ template void Sort( T &source[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH, int maxAllowed = 0 // ) { // int idx = -1; bool has = false; // // Validate ... has = IsXValid(sortBy) && HasChild(source) && HasDirection(sortDir); if (!has) { return; } // // Copy source for Manipulating ... T tmps[]; Copy( source, tmps // ); // // Clean Source Collection for Adding Sorted Items ... Clean(source); // // Loop Through Temp Collection Has Child ... while (HasChild(tmps)) { // // Select Based on Sorting Parameter ... idx = SelectItemForSorting( tmps, sortBy, sortDir // ); // // Validate Detected Index ... has = IsValidIndex(idx); if (!has) { break; } // // Add Detected Indexed Item to Source ... AddRef( tmps[idx], source // ); // // Remove Item From Temp Collection ... ArrayRemove( tmps, idx, 1 // ); } // // Cleanup Collection if Max Items Reached ... if (maxAllowed > 0) { // CleanupArray( source, maxAllowed // ); } // // Cleanup Resources ... SpecifiedClean(tmps); } /** * Apply Sort on Specified Collection ... * * @param source: Collection Reference to Sort ... * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... * @param priceType: ENUM_X_PRICE, Price Selecting Method ... * @param maxAllowed: int, Max Allowed Collection Size ... */ void SortBar( XOHCL &source[], ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH, ENUM_X_PRICE priceType = X_PRICE_NONE, int maxAllowed = 0 // ) { // int idx = -1; bool has = false; // // Validate ... has = IsXValid(sortBy) && HasChild(source) && HasDirection(sortDir); if (!has) { return; } // // Copy source for Manipulating ... XOHCL tmps[]; Copy( source, tmps // ); // // Clean Source Collection for Adding Sorted Items ... Clean(source); // // Loop Through Temp Collection Has Child ... while (HasChild(tmps)) { // // Select Based on Sorting Parameter ... idx = SelectBarForSorting( tmps, sortBy, sortDir, priceType // ); // // Validate Detected Index ... has = IsValidIndex(idx); if (!has) { break; } // // Add Detected Indexed Item to Source ... AddRef( tmps[idx], source // ); // // Remove Item From Temp Collection ... ArrayRemove( tmps, idx, 1 // ); } // // Cleanup Collection if Max Items Reached ... if (maxAllowed > 0) { // CleanupArray( source, maxAllowed // ); } // // Cleanup Resources ... SpecifiedClean(tmps); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Extraction | //+------------------------------------------------------------------+ /** * Extract Specific Types of Pivots From a Collection ... * * @param dest: reference Collection to Hold result ... * @param source: Collection to Find Type Specific items ... * @param _type: Specified item Type ... * * @return ( int ) */ int ExtractPivots( XPivot &dest[], XPivot &source[], ENUM_X_PIVOT_TYPE _type // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... int count = ArraySize(source); bool has = IsXValid(_type) && IsValidSize(count); if (!has) { return result; } // for (int i = 0; i < count; i++) { // // Check Type Passing ... has = _type == source[i].type; if (!has) { continue; } // AddIfNotExists( source[i], dest // ); } // result = ArraySize(dest); // return result; } /** * Extract Same Time Pivots ... * * @param item: XPivot, reference to Specified Pivot for Detect Same Times ... * @param dest: XPivot, collection reference to holds Same Times Pivots ... * @param source: XPivot, collection reference to Provide Data Source ... * * @return ( int ) */ int ExtractSameTimePivots( XPivot &item, XPivot &dest[], XPivot &source[] // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = HasChild(source) && item.IsValid(); if (!has) { return result; } // // Do ... int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = item.time == source[i].time; if (has) { AddIfNotExists(source[i], dest); } } // // Add item as a Child ... AddIfNotExists(item, dest); // result = ArraySize(dest); // return result; } /** * Extract Pivots Data for Linear Regression Calculations ... * * @param xData: refrence Collection to Holds X-Axis Data ... * @param yData: refrence Collection to Holds Y-Axis Data ... * @param source: pivots Collection for Extraction ... * * @return ( int ) */ int ExtractPivotsData( double &xData[], double &yData[], XPivot &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(xData); SpecifiedClean(yData); // // Validate ... int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XOHCL iBar; bool has = false; double iX = EMPTY_VALUE; double iY = EMPTY_VALUE; for (int i = 0; i < count; i++) { // // Get Pivot Bar ... has = source[i].GetBar(iBar); if (!has) { continue; } // iX = iBar.Index(); iY = source[i].value; // Add( iX, xData // ); // Add( iY, yData // ); // iBar.Clean(); } // iBar.Clean(); // result = MathMin(ArraySize(xData), ArraySize(yData)); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Support and Resistance | //+------------------------------------------------------------------+ /** * Extract Support Levels of Pivots Collection ... * * @param _minor: refrence to Holds Minor Level ... * @param _major: refrence to Holds Major Level ... * @param source: Collection of Pivots ... * * @return ( bool ) */ bool ExtractSupport( double &_minor, double &_major, XPivot &source[] // ) { // bool result = false; // // Prepare ... _minor = EMPTY_VALUE; _major = EMPTY_VALUE; // // Validate ... int count = ArraySize(source); result = IsValidSize(count); if (!result) { return result; } // bool has = false; double tmp = EMPTY_VALUE; double iValue = EMPTY_VALUE; for (int i = 0; i < count; i++) { // // Check Type ... has = source[i].IsVale(); if (!has) { continue; } // // Reading Value ... iValue = source[i].value; // // Check Can Change Major ... has = !NotEmpty(_major) || _major > iValue; if (has) { // tmp = _major; _major = iValue; } // // Check Can Change Minor ... else { // // Change Minor ... has = !NotEmpty(tmp) || tmp > iValue; if (has) { tmp = iValue; } } } // // Last Update of Minore Minor ... has = NotEmpty(tmp); if (has) { _minor = tmp; } // result = NotEmpty(_major) || NotEmpty(_minor); // return result; } /** * Extract Resistance Levels of Pivots Collection ... * * @param _minor: refrence to Holds Minor Level ... * @param _major: refrence to Holds Major Level ... * @param source: Collection of Pivots ... * * @return ( bool ) */ bool ExtractResistances( double &_minor, double &_major, XPivot &source[] // ) { // bool result = false; // // Prepare ... _minor = EMPTY_VALUE; _major = EMPTY_VALUE; // // Validate ... int count = ArraySize(source); result = IsValidSize(count); if (!result) { return result; } // bool has = false; double tmp = EMPTY_VALUE; double iValue = EMPTY_VALUE; for (int i = 0; i < count; i++) { // // Check Type ... has = source[i].IsPeak(); if (!has) { continue; } // // Reading Value ... iValue = source[i].value; // // Check Can Change Major ... has = !NotEmpty(_major) || _major < iValue; if (has) { // tmp = _major; _major = iValue; } // // Check Can Change Minor ... else { // // Change Minor ... has = !NotEmpty(tmp) || tmp < iValue; if (has) { tmp = iValue; } } } // // Last Update of Minore Minor ... has = NotEmpty(tmp); if (has) { _minor = tmp; } // result = NotEmpty(_major) || NotEmpty(_minor); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Find Index | //+------------------------------------------------------------------+ /** * Find Specified Item index in a Collection ... * * @param index: int, reference to Hold Index if Exists ... * @param item: Specified item to Detect ... * @param source: Collection to Search for item ... * * @return ( bool ) */ bool FindIndex( int &index, XBoxZone &item, XBoxZone &source[] // ) { // bool result = false; // index = -1; // int count = ArraySize(source); result = item.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // bool isSame = item.IsSameAs(source[i]); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Find Specified Item index in a Collection ... * * @param index: int, reference to Hold Index if Exists ... * @param item: Specified item to Detect ... * @param source: Collection to Search for item ... * * @return ( bool ) */ bool FindIndex( int &index, XPivot &item, XPivot &source[] // ) { // bool result = false; // index = -1; // int count = ArraySize(source); result = item.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // bool isSame = item.IsSameAs(source[i]); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } /** * Find Specified Item index in a Collection ... * * @param index: int, reference to Hold Index if Exists ... * @param item: Specified item to Detect ... * @param source: Collection to Search for item ... * * @return ( bool ) */ bool FindIndex( int &index, XDirectionShift &item, XDirectionShift &source[] // ) { // bool result = false; // index = -1; // int count = ArraySize(source); result = item.IsValid() && IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // bool isSame = item.IsSameAs(source[i]); if (isSame) { // index = i; break; } } // result = IsValidIndex(index); // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Remove | //+------------------------------------------------------------------+ /** * Remove Specified Item from a Collection ... * * @param item: Specified Item ... * @param source: Specified Collection for Remove item from it ... * * @return ( bool ) */ bool Remove( XPivot &item, XPivot &source[] // ) { // bool result = false; // result = item.IsValid() && HasChild(source); if (!result) { return result; } // int idx = -1; result = FindIndex( idx, item, source // ); if (!result) { return result; } // result = ArrayRemove( source, idx, 1 // ); // return result; } /** * Remove Specified Item from a Collection ... * * @param item: Specified Item ... * @param source: Specified Collection for Remove item from it ... * * @return ( bool ) */ bool Remove( XBoxZone &item, XBoxZone &source[] // ) { // bool result = false; // result = item.IsValid() && HasChild(source); if (!result) { return result; } // int idx = -1; result = FindIndex( idx, item, source // ); if (!result) { return result; } // result = ArrayRemove( source, idx, 1 // ); // return result; } /** * Remove Specified Item from a Collection ... * * @param item: Specified Item ... * @param source: Specified Collection for Remove item from it ... * * @return ( bool ) */ bool Remove( XDirectionShift &item, XDirectionShift &source[] // ) { // bool result = false; // result = item.IsValid() && HasChild(source); if (!result) { return result; } // int idx = -1; result = FindIndex( idx, item, source // ); if (!result) { return result; } // result = ArrayRemove( source, idx, 1 // ); // return result; } /** * Remove Specified items from a Collection ... * * @param items: Specified Items to Remove ... * @param sources: Sepcified Collection for Removing items from it ... * * @return ( int ) */ int Removes( XBoxZone &items[], XBoxZone &sources[] // ) { // int result = 0; // bool has = HasChild(items) && HasChild(sources); if (!has) { return result; } // int idx = -1; has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // // Detect Item Index in Collection ... has = FindIndex( idx, items[i], sources // ); if (has) { // // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, 1 // ); // if (has) { // // Count Removed Items ... result++; } } } // return result; } /** * Remove Specified items from a Collection ... * * @param items: Specified Items to Remove ... * @param sources: Sepcified Collection for Removing items from it ... * * @return ( int ) */ int Removes( XPivot &items[], XPivot &sources[] // ) { // int result = 0; // bool has = HasChild(items) && HasChild(sources); if (!has) { return result; } // int idx = -1; has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // // Detect Item Index in Collection ... has = FindIndex( idx, items[i], sources // ); if (has) { // // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, 1 // ); // if (has) { // // Count Removed Items ... result++; } } } // return result; } /** * Remove Specified items from a Collection ... * * @param items: Specified Items to Remove ... * @param sources: Sepcified Collection for Removing items from it ... * * @return ( int ) */ int Removes( XDirectionShift &items[], XDirectionShift &sources[] // ) { // int result = 0; // bool has = HasChild(items) && HasChild(sources); if (!has) { return result; } // int idx = -1; has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // // Detect Item Index in Collection ... has = FindIndex( idx, items[i], sources // ); if (has) { // // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, 1 // ); // if (has) { // // Count Removed Items ... result++; } } } // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Add If Not Exists | //+------------------------------------------------------------------+ /** * Add Specified Item to Specified Collection, if not Exists ... * * @param item: Item to Add ... * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) */ bool AddIfNotExists( XBoxZone &item, XBoxZone &sources[], int maxAllowed = 0 // ) { // bool result = false; // // Validate Args ... result = item.IsValid(); if (!result) { return result; } // // Check Item Exists or not ... int idx = -1; bool isExists = FindIndex( idx, item, sources // ); result = !isExists; if (!result) { return result; } // AddRef( item, sources // ); // // Handle Cleanup Collection // if Max Reached ... if (result && maxAllowed > 0) { // CleanupArray( sources, maxAllowed // ); } // return result; } /** * Add Specified Item to Specified Collection, if not Exists ... * * @param item: Item to Add ... * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) */ bool AddIfNotExists( XPivot &item, XPivot &sources[], int maxAllowed = 0 // ) { // bool result = false; // // Validate Args ... result = item.IsValid(); if (!result) { return result; } // // Check Item Exists or not ... int idx = -1; bool isExists = FindIndex( idx, item, sources // ); result = !isExists; if (!result) { return result; } // AddRef( item, sources // ); // // Handle Cleanup Collection // if Max Reached ... if (result && maxAllowed > 0) { // CleanupArray( sources, maxAllowed // ); } // return result; } /** * Add Specified Item to Specified Collection, if not Exists ... * * @param item: Item to Add ... * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) */ bool AddIfNotExists( XDirectionShift &item, XDirectionShift &sources[], int maxAllowed = 0 // ) { // bool result = false; // // Validate Args ... result = item.IsValid(); if (!result) { return result; } // // Check Item Exists or not ... int idx = -1; bool isExists = FindIndex( idx, item, sources // ); result = !isExists; if (!result) { return result; } // AddRef( item, sources // ); // // Handle Cleanup Collection // if Max Reached ... if (result && maxAllowed > 0) { // CleanupArray( sources, maxAllowed // ); } // return result; } template int FillNotExists( T &dest[], T &source[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, int maxAllowed = 0 // ) { // int result = 0; // // Prepare ... XClean(dest); // // Normalize ... maxAllowed = NormalizeInt(maxAllowed, 0); // // Validate ... bool has = HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = source[i].IsValid() && (!HasDirection(forDir) || forDir == source[i].dir); if (!has) { continue; } // has = AddIfNotExists(source[i], dest); if (has) { result++; } } // // Handle Cleanup Collection // if Max Reached ... if (maxAllowed > 0) { // CleanupArray( dest, maxAllowed // ); } // return result; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Extract | //+------------------------------------------------------------------+ /** * Extract Specified Directional Items ... * * @param dest: reference collection to holds extracted items ... * @param source: reference collection to provides data source ... * @param forDir: Specified which direction to Extract items ... * * @return ( int ) */ template int ExtractByDirection( T &dest[], T &source[], ENUM_X_DIRECTION forDir // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = HasChild(source) && HasDirection(forDir); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = source[i].dir == forDir; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } //+------------------------------------------------------------------+ // // // //+------------------------------------------------------------------+ //| Other Extensions | //+------------------------------------------------------------------+ /** * Validate Boxes ... * @param box: XBoxZone instance reference for Validate ... * @param barIndex: int, Bar Index ... * @param barsLength: int, Bars Length for Validation ... * * @return ( bool ) */ bool IsBoxValid( XBoxZone &box, int barIndex = 0, int barsLength = 3 // ) { // bool result = false; // // Normalize Bar Index ... barIndex = NormalizeInt(barIndex, 0); barsLength = NormalizeInt(barsLength, 1); // // Ceck Input Box is Valid ... result = box.IsValid(); if (!result) { return result; } // // Check Input Box is Breaked or not ... // Breaktion Found using Counting Over/Under Close Bars ... bool isBullish = box.IsBullish(); double appliedPrice = box.GetInDirectionalPrice(); result = NotEmptyZero(appliedPrice); if (!result) { return result; } // int toIDX = box.ToIndex(); // XOHCL iBar; int edgeBreakes = 0; for (int i = barIndex; i <= toIDX; i++) { // // Initialize Indexed Bar ... result = iBar.Init( box.symbol, box.period, i // ); // // Checking Price ... result = // // Checking Bar Validation ... result && // // Checking Price Breaked or not ... (isBullish ? iBar.close < box.lower : iBar.close > box.upper); if (result) { edgeBreakes++; } else { edgeBreakes = 0; } // result = edgeBreakes >= barsLength; if (result) { break; } // iBar.Clean(); } // iBar.Clean(); // // return true; // result = edgeBreakes < barsLength; // return result; } // void SortBoxes( XBoxZone &items[], int maxAllowed = 0 // ) { // int idx = -1; bool has = false; // has = HasChild(items); if (!has) { return; } // XBoxZone tmp[]; Copy( items, tmp // ); Clean(items); // while (HasChild(tmp)) { // idx = GetOldest(tmp); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmp[idx]; ArrayRemove( tmp, idx, 1 // ); // AddRef( iBox, items // ); } // if (maxAllowed > 0) { // CleanupArray( items, maxAllowed // ); } // Clean(tmp); } /** * Check a BaxHas Valid Place for Specified Bar ... * * @param bar: XOHCL instance reference, Specified Bar ... * #param box: XBoxZone instance reference, Specified Box ... * * @return ( bool ) */ bool IsBoxPlaceValidForBar( XOHCL &bar, XBoxZone &box // ) { // bool result = false; // result = bar.IsValid() && box.IsValid(); if (!result) { return result; } // result = box.IsBullish() ? bar.low > box.upper : bar.high < box.upper; // return result; } // void ValidateBoxes( XBoxZone &boxes[], int barIndex = 0, int barsLength = 3, bool forceSorting = false, int maxAllowed = 0 // ) { // bool has = false; // // Normalize Args ... barIndex = NormalizeInt(barIndex, 0); barsLength = NormalizeInt(barsLength, 3); // // Validate Args ... has = HasChild(boxes); if (!has) { return; } // // Copy Boxes to tmp ... XBoxZone tmp[]; Copy( boxes, tmp // ); Clean(boxes); // // Looping Through Exists Boxes ... while (HasChild(tmp)) { // // Select Indexed Box ... XBoxZone iBox = tmp[0]; // // Remove Indexed Box ... ArrayRemove( tmp, 0, 1 // ); // // Check Box Validating ... has = IsBoxValid( iBox, barIndex, barsLength // ); if (has) { // AddRef( iBox, boxes // ); } } // // Sorting ... if (forceSorting) { // // Check Has Result or not ... has = HasChild(boxes); if (has) { // // Sorting ... SortBoxes( boxes, maxAllowed // ); } } // } void UpdateToTime( XBoxZone &zones[], datetime toTime = NULL // ) { // // Normalize ... toTime = NormalizeTime(toTime); // // Validate ... bool has = HasChild(zones); if (!has) { return; } // int count = ArraySize(zones); for (int i = 0; i < count; i++) { zones[i].to = toTime; } } /** * Remove Breaked Zones from a Collection ... * * @param source: XBoxZone, reference to Specified Collection ... * * @return ( int ) */ int RemoveBreakedZones( XBoxZone &source[], bool forceBreak = false // ) { // int result = 0; // // Validate ... bool has = HasChild(source); if (!has) { return result; } // XBoxZone iZone; XBoxZone tmps[]; Copy( source, tmps // ); XClean(source); XOHCL tmpBars[]; int breakerBars = 0; while (HasChild(tmps)) { // iZone.Clean(); iZone = tmps[0]; ArrayRemove(tmps, 0, 1); has = IsXValid(iZone.breakAt); if (has) { continue; } // if (forceBreak) { // breakerBars = GetBreakerBars(iZone, tmpBars); has = IsValidSize(breakerBars); } if (has) { continue; } // AddIfNotExists( iZone, source // ); } // result = ArraySize(source); // return result; } /** * Remove Filled Zones ... * * @param source: XBoxZone, collection reference to Provide Data Source ... * @param zoneRangeFilledFactor: double, Filling Factor ... * * @return ( int ) */ int RemoveFilledZones( XBoxZone &source[], double zoneRangeFilledFactor = 0.8 // ) { // int result = 0; // // Validate ... bool has = HasChild(source); if (!has) { return result; } // XBoxZone iTMP; XBoxZone tmp[]; Copy(source, tmp); XClean(source); while (HasChild(tmp)) { // iTMP.Clean(); iTMP = tmp[0]; ArrayRemove(tmp, 0, 1); // has = IsFilled(iTMP, zoneRangeFilledFactor); if (!has) { AddIfNotExists(iTMP, source); } } // result = ArraySize(source); // return result; } // #region Zone Converters ... /** * Converts a Bar to Pivot ... * * @param bar: XOHCL, reference to Specified Bar ... * @param pivot: XPivot, reference to holds result ... * @param forDir: ENUM_X_DIRECTION, specified Pivot Direction ... * @param prefix: string, Specified Pivot Prefix (used for Object Type) ... * @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ... * @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ... * * @return ( bool ) */ bool ToPivot( XOHCL &bar, XPivot &pivot, ENUM_X_DIRECTION forDir, string prefix = NULL, ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE valePriceType = X_PRICE_LOW // ) { // bool result = false; // // Prepare ... pivot.Clean(); // // Normalize ... if (!IsXValid(peakPriceType)) { peakPriceType = X_PRICE_HIGH; } if (!IsXValid(valePriceType)) { valePriceType = X_PRICE_LOW; } // // Validate ... result = bar.IsValid() && HasDirection(forDir) && IsXValid(peakPriceType) && IsXValid(valePriceType); if (!result) { return result; } // // Check Direction ... bool isBullish = IsSpecifiedBullish(forDir); // // Prepare Value of Pivot ... double iValue = isBullish ? bar.GetPrice(valePriceType) : bar.GetPrice(peakPriceType); // // Prepare Pivot Type ... ENUM_X_PIVOT_TYPE iType = isBullish ? X_PIVOT_TYPE_VALE : X_PIVOT_TYPE_PEAK; // // Initialize Pivot ... result = pivot.Init( iValue, bar.time, bar.symbol, forDir, bar.period, iType // ); if (result) { // // Set Prefix if Pivot initialized successfully ... pivot.prefix = prefix; } // // Validate ... result = pivot.IsValid(); if (!result) { pivot.Clean(); } // return result; } /** * Converts a Bar to Pattern Pivot ... * * @param bar: XOHCL, reference to Specified Bar ... * @param pivot: XPivot, reference to holds result ... * @param patternDir: ENUM_X_DIRECTION, specified Pivot Direction ... * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern Type ... * @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ... * @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ... * * @return ( bool ) */ bool ToPivot( XOHCL &bar, XPivot &pivot, ENUM_X_DIRECTION patternDir, ENUM_X_BAR_PATTERN pattern, ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE valePriceType = X_PRICE_LOW // ) { // bool result = false; // // Prepare ... pivot.Clean(); // // Normalize ... if (!IsXValid(peakPriceType)) { peakPriceType = X_PRICE_HIGH; } if (!IsXValid(valePriceType)) { valePriceType = X_PRICE_LOW; } // // Validate ... result = bar.IsValid() && IsXValid(pattern) && IsXValid(peakPriceType) && IsXValid(valePriceType) && HasDirection(patternDir); if (!result) { return result; } // datetime iTime = bar.time; string iSymbol = bar.symbol; string iPrefix = ToXString(pattern); ENUM_TIMEFRAMES iPeriod = bar.period; double iValue = IsXBullish(patternDir) ? bar.GetPrice(X_PRICE_LOW) : IsXBearish(patternDir) ? bar.GetPrice(X_PRICE_HIGH) : EMPTY_VALUE; ENUM_X_PIVOT_TYPE iType = IsXBullish(patternDir) ? X_PIVOT_TYPE_VALE : IsXBearish(patternDir) ? X_PIVOT_TYPE_PEAK : X_PIVOT_TYPE_NONE; // result = pivot.Init( iValue, iTime, iSymbol, patternDir, iPeriod, iType // ); if (result) { pivot.prefix = iPrefix; } // // Cleanup Resources ... if (!result) { pivot.Clean(); } // return result; } /** * Converts POI Bar to Box ... * * @param bar: XOHCL, reference to Specified Pattern ... * @param box: XBoxZone, reference to holds result ... * @param forDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * @param prefix: string, Specified Pattern Type ... * @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ... * @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ... * @param setFromByBreakerBar: bool, Set Box From Time to Breaker Bar ... * * @return ( bool ) */ bool ToBox( XOHCL &bar, XBoxZone &box, ENUM_X_DIRECTION forDir, string prefix = NULL, ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE valePriceType = X_PRICE_LOW, bool setFromByBreakerBar = false // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... if (!IsXValid(peakPriceType)) { peakPriceType = X_PRICE_HIGH; } if (!IsXValid(valePriceType)) { valePriceType = X_PRICE_LOW; } // // Validate ... result = bar.IsValid() && HasDirection(forDir) && IsXValid(peakPriceType) && IsXValid(valePriceType); if (!result) { return result; } // // Check if is Valid Pattern ... ENUM_X_BAR_PATTERN iPattern = ToBarPattern(prefix); result = IsXValid(iPattern); if (result) { // // Conver to Box as Pattern ... result = ToBox( bar, box, forDir, iPattern, peakPriceType, valePriceType, setFromByBreakerBar // ); } // // There is not any Valid Pattern Provided ... else { // bool isBullish = IsXBullish(forDir); double peakPrice = bar.GetPrice(peakPriceType); double valePrice = bar.GetPrice(valePriceType); // string iType = prefix; datetime iAt = bar.time; datetime iTo = bar.time; double iUpper = peakPrice; double iLower = valePrice; string iSymbol = bar.symbol; datetime iFrom = bar.BeforeOn(); ENUM_TIMEFRAMES iPeriod = bar.period; // // Assign Values to Box ... box.at = iAt; box.to = iTo; box.from = iFrom; box.type = iType; box.dir = forDir; box.upper = iUpper; box.lower = iLower; box.symbol = iSymbol; box.period = iPeriod; } // // Validate result ... result = box.IsValid(); if (!result) { // box.Clean(); return result; } // return result; } /** * Converts Pattern Bar to Box ... * * @param bar: XOHCL, reference to Specified Pattern ... * @param box: XBoxZone, reference to holds result ... * @param forDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * @param prefix: string, Specified Pattern Type ... * @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ... * @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ... * @param setFromByBreakerBar: bool, Set Box From Time to Breaker Bar ... * * @return ( bool ) */ bool ToBox( XOHCL &bar, XBoxZone &box, ENUM_X_DIRECTION patternDir, ENUM_X_BAR_PATTERN pattern, ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE valePriceType = X_PRICE_LOW, bool setFromByBreakerBar = false // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... if (!IsXValid(peakPriceType)) { peakPriceType = X_PRICE_HIGH; } if (!IsXValid(valePriceType)) { valePriceType = X_PRICE_LOW; } // // Validate ... result = bar.IsValid() && IsXValid(pattern) && IsXValid(peakPriceType) && IsXValid(valePriceType) && HasDirection(patternDir); if (!result) { return result; } // // Define Requirements ... XOHCL tmpBar; XBoxZone tmpBox; bool has = false; datetime iAt = bar.time; datetime iTo = bar.time; double iUpper = EMPTY_VALUE; double iLower = EMPTY_VALUE; string iSymbol = bar.symbol; datetime iFrom = bar.BeforeOn(); string iType = ToXString(pattern); ENUM_TIMEFRAMES iPeriod = bar.period; // bool isBullish = IsXBullish(patternDir); double peakPrice = bar.GetPrice(peakPriceType); double valePrice = bar.GetPrice(valePriceType); // // Calculate Requirements Based on Pattern Type and Direction ... switch (pattern) { // case X_BAR_PATTERN_HIGH: { // if (setFromByBreakerBar) { // tmpBar.Clean(); has = GetBreakerBar( bar, tmpBar, peakPriceType, peakPriceType, X_DIRECTION_BULLISH // ); if (has) { iFrom = tmpBar.time; } } // iUpper = peakPrice; iLower = bar.GetUp(); } break; // case X_BAR_PATTERN_LOW: { // if (setFromByBreakerBar) { // tmpBar.Clean(); has = GetBreakerBar( bar, tmpBar, valePriceType, valePriceType, X_DIRECTION_BEARISH // ); if (has) { iFrom = tmpBar.time; } } // iUpper = bar.GetDown(); iLower = valePrice; } break; // case X_BAR_PATTERN_MOMENTUM: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = peakPrice; iLower = valePrice; } break; // case X_BAR_PATTERN_ENGULFED: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = peakPrice; iLower = valePrice; } break; // case X_BAR_PATTERN_TRUE_GAPED: { // tmpBar.Clean(); has = bar.GetPreviousBar(tmpBar); if (has) { // iFrom = tmpBar.time; // iUpper = isBullish ? valePrice : tmpBar.GetPrice(valePriceType); iLower = isBullish ? tmpBar.GetPrice(peakPriceType) : peakPrice; } } break; // case X_BAR_PATTERN_PINNED: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = isBullish ? bar.GetDown() : peakPrice; iLower = isBullish ? valePrice : bar.GetUp(); } break; // case X_BAR_PATTERN_STAR: { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { // if (setFromByBreakerBar) { iFrom = tmpBar.time; } // int idx = -1; int mLength = tmpBar.Index() - bar.Index(); iLower = bar.FindLowest(idx, mLength, valePriceType); iUpper = bar.FindHighest(idx, mLength, peakPriceType); } } break; // case X_BAR_PATTERN_PIERCING: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = peakPrice; iLower = valePrice; } break; // case X_BAR_PATTERN_RISING: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = peakPrice; iLower = valePrice; } break; // case X_BAR_PATTERN_FLAG: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // int idx = -1; int mLength = 3; iUpper = bar.FindHighest(idx, mLength, peakPriceType); iLower = bar.FindLowest(idx, mLength, valePriceType); } break; // case X_BAR_PATTERN_SIGNALKEY: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // has = bar.GetPreviousBar(tmpBar); if (has) { // iUpper = MathMax(peakPrice, tmpBar.GetPrice(peakPriceType)); iLower = MathMin(valePrice, tmpBar.GetPrice(valePriceType)); } } break; // case X_BAR_PATTERN_OB: { // tmpBox.Clean(); has = ToOBBox( bar, tmpBox, patternDir // ); if (has) { // iFrom = tmpBox.from; iUpper = tmpBox.upper; iLower = tmpBox.lower; } } break; // case X_BAR_PATTERN_FVG: { // tmpBox.Clean(); has = ToFVGBox( bar, tmpBox, patternDir // ); if (has) { // iFrom = tmpBox.from; iUpper = tmpBox.upper; iLower = tmpBox.lower; } } break; // case X_BAR_PATTERN_SUPPORT: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = isBullish ? peakPrice : valePrice; iLower = isBullish ? peakPrice : valePrice; } break; // case X_BAR_PATTERN_RESISTANCE: { // if (setFromByBreakerBar) { // tmpBar.Clean(); ENUM_X_PRICE iPType = isBullish ? valePriceType : peakPriceType; has = GetBreakerBar( bar, tmpBar, iPType, iPType, patternDir // ); if (has) { iFrom = tmpBar.time; } } // iUpper = isBullish ? peakPrice : valePrice; iLower = isBullish ? peakPrice : valePrice; } break; } // // Assign Values to Box ... box.at = iAt; box.to = iTo; box.from = iFrom; box.type = iType; box.upper = iUpper; box.lower = iLower; box.symbol = iSymbol; box.period = iPeriod; box.dir = patternDir; // result = box.IsValid(); // // Cleanup Resources ... if (!result) { box.Clean(); } tmpBar.Clean(); tmpBox.Clean(); // return result; } /** * Converts Order Flow to Zone ... * * @param zone: XBoxZone, reference to holds result ... * @param orderFlow: XBoxZone, collection reference to provides order flow ... * * @return ( bool ) */ bool ToBox( XBoxZone &zone, XBoxZone &orderFlow[] // ) { // bool result = false; // // Prepare ... zone.Clean(); // // Validate ... result = HasChild(orderFlow); if (!result) { return result; } // zone = orderFlow[0]; int idx = GetHighest(orderFlow); if (IsValidIndex(idx)) { zone.upper = orderFlow[idx].upper; } idx = GetLowest(orderFlow); if (IsValidIndex(idx)) { zone.lower = orderFlow[idx].lower; } // zone.type = "XOrderFlowP"; // result = zone.IsValid(); // return result; } /** * Converts a Bar to OB Box ... * * @param bar: XOHCL, Specified Bar ... * @param box: XBoxZone, destination Box ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( bool ) */ bool ToOBBox( XOHCL &bar, XBoxZone &box, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... if (!HasDirection(forDir)) { forDir = bar.GetDirection(); } // // Validate ... result = bar.IsValid() && HasDirection(forDir) && bar.GetDirection() == forDir; if (!result) { return result; } // // Detect OB Start Bar ... XOHCL obStartBar; result = GetDirectionalBar( bar, obStartBar, Opposit(forDir) // ); if (!result) { // obStartBar.Clean(); return result; } // box.dir = forDir; box.to = bar.time; box.at = bar.time; box.symbol = bar.symbol; box.period = bar.period; box.from = obStartBar.time; box.type = ToXString(X_BAR_PATTERN_OB); box.lower = MathMin(obStartBar.low, bar.low); box.upper = MathMax(obStartBar.high, bar.high); // result = box.IsValid(); // // Cleanup Resources ... if (!result) { box.Clean(); } obStartBar.Clean(); // return result; } /** * Converts a Bar to FVG Box ... * * @param bar: XOHCL, Specified Bar ... * @param box: XBoxZone, destination Box ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( bool ) */ bool ToFVGBox( XOHCL &bar, XBoxZone &box, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... if (!HasDirection(forDir)) { forDir = bar.GetDirection(); } // // Validate ... result = bar.IsValid() && HasDirection(forDir) && bar.GetDirection() == forDir; if (!result) { return result; } // // Detect FVG Start Bar ... XOHCL fvgStartBar; result = bar.BarAt( bar.Index() + 2, fvgStartBar); if (!result) { // fvgStartBar.Clean(); return result; } // bool isBullish = IsXBullish(forDir); // box.dir = forDir; box.to = bar.time; box.at = bar.time; box.upper = isBullish ? bar.low : bar.high; box.symbol = bar.symbol; box.period = bar.period; box.lower = isBullish ? fvgStartBar.high : fvgStartBar.low; box.from = fvgStartBar.time; box.type = ToXString(X_BAR_PATTERN_FVG); // result = box.IsValid(); // // Cleanup Resources ... if (!result) { box.Clean(); } fvgStartBar.Clean(); // return result; } /** * Converts a Bar to Support Box ... * * @param bar: XOHCL, Specified Bar ... * @param box: XBoxZone, destination Box ... * @param toTime: datetime, Specified Box to Time ... * * @return ( bool ) */ bool ToSupportBox( XOHCL &bar, XBoxZone &box, datetime toTime = NULL, int validationLength = 0 // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... toTime = NormalizeTime(toTime); validationLength = NormalizeInt(validationLength, 0); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL breaker; result = GetBreakerBar( bar, breaker, X_PRICE_LOW, X_PRICE_DOWN, X_DIRECTION_BEARISH, 500 // ); if (!result) { breaker.Clean(); } // box.to = toTime; box.at = bar.time; box.from = breaker.IsValid() ? breaker.time : validationLength <= 0 ? bar.time : GetBarTime( bar.symbol, bar.period, bar.Index() + validationLength // ); box.lower = bar.low; box.symbol = bar.symbol; box.period = bar.period; box.upper = bar.GetDown(); box.dir = X_DIRECTION_BULLISH; box.type = ToXString(X_BAR_PATTERN_SUPPORT); // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } /** * Converts a Bar to Resistance Box ... * * @param bar: XOHCL, Specified Bar ... * @param box: XBoxZone, destination Box ... * @param toTime: datetime, Specified Box to Time ... * * @return ( bool ) */ bool ToResistanceBox( XOHCL &bar, XBoxZone &box, datetime toTime = NULL, int validationLength = 0 // ) { // bool result = false; // // Prepare ... box.Clean(); // // Normalize ... toTime = NormalizeTime(toTime); validationLength = NormalizeInt(validationLength, 0); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // XOHCL breaker; result = GetBreakerBar( bar, breaker, X_PRICE_HIGH, X_PRICE_UP, X_DIRECTION_BULLISH, 500 // ); if (!result) { breaker.Clean(); } // box.to = toTime; box.at = bar.time; box.from = breaker.IsValid() ? breaker.time : validationLength <= 0 ? bar.time : GetBarTime( bar.symbol, bar.period, bar.Index() + validationLength // ); box.upper = bar.high; box.symbol = bar.symbol; box.period = bar.period; box.lower = bar.GetUp(); box.dir = X_DIRECTION_BEARISH; box.type = ToXString(X_BAR_PATTERN_RESISTANCE); // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } // #endregion // #region Zone Checkers ... /** * Check a Zone is Filled or Not ... * * @param zone: XBoxZone, reference to Specified Zone ... * @param zoneRangeFilledFactor: double, Filling Factor ... * * @return ( bool ) */ bool IsFilled( XBoxZone &zone, double zoneRangeFilledFactor = 0.8 // ) { // bool result = false; // // Validate ... result = zone.IsValid() && zoneRangeFilledFactor > 0 && zoneRangeFilledFactor < 1; if (!result) { // result = true; return result; } // XOHCL iBar; int toIDX = zone.ToIndex(); int fromIDX = zone.FromIndex(); double zoneRangeFactor = zone.GetRange() / 100; double useValue = zone.lower + (zoneRangeFactor * zoneRangeFilledFactor); for (int i = toIDX; i < fromIDX; i++) { // // Initialize Indexed Bar ... iBar.Clean(); result = iBar.Init(zone.symbol, zone.period, i); result = result && (zone.IsBullish() ? iBar.GetPrice(X_PRICE_LOW) <= useValue : iBar.GetPrice(X_PRICE_HIGH) >= useValue); if (result) { break; } } // // Cleanup ... iBar.Clean(); // return result; } /** * Check Specified Zone is Breaked by Specified Bar or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * @param forceBarEdge: bool, flag to Check Breaktion by high ot low ... * * @return ( bool ) */ bool IsBreaked( XOHCL &bar, XBoxZone &zone, bool forceBarEdge = false // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Check Break ... result = zone.IsBullish() ? bar.close < zone.lower : bar.close > zone.upper; // // Apply Force Bar Edge ... if (forceBarEdge) { // result = result && zone.IsBullish() ? bar.low > zone.upper : bar.high < zone.lower; } // return result; } /** * Check Specified Zone is Tested by Specified Bar or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * * @return ( bool ) */ bool IsTested( XOHCL &bar, XBoxZone &zone // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Check Test ... result = zone.IsBullish() ? bar.low < zone.upper && bar.low > zone.lower : bar.high > zone.lower && bar.high < zone.upper; // return result; } /** * Check Specified Zone is Rejected by Specified Bar or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * * @return ( bool ) */ bool IsRejected( XOHCL &bar, XBoxZone &zone // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Check Test ... result = IsTested(bar, zone) && (zone.IsBullish() ? bar.GetDown() >= zone.upper : bar.GetUp() <= zone.lower); // return result; } /** * Check Specified Bar is Inside Specified Zone or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * * @return ( bool ) */ bool IsInside( XOHCL &bar, XBoxZone &zone // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Check Inside ... result = zone.IsBullish() ? bar.low < zone.upper && bar.low > zone.lower : bar.high > zone.lower && bar.high < zone.upper; // return result; } /** * Check Specified Bar is Acted On Specified Zone or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * * @return ( bool ) */ bool IsActed( XOHCL &bar, XBoxZone &zone // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Get Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Previous Bar must one of Following States: // - Tested; // - Inside; // - Breaked; bool isTested = IsTested(pBar, zone); bool isInside = IsInside(pBar, zone); bool isBreaked = IsBreaked(pBar, zone); result = isTested || isInside || isBreaked; if (!result) { return result; } // // Current Bar Must Close Over / Under Zone ... result = zone.IsBullish() ? bar.close > zone.upper : zone.IsBearish() ? bar.close < zone.lower : false; // // Cleanup Resources ... pBar.Clean(); // return result; } /** * Check Specified Zone is Breaked or not ... * * @param zone: XBoxZone, reference to Specified Zone ... * @param priceType: ENUM_X_PRICE, Specified Price Type for Zone Break Detection ... * * @return ( bool ) */ bool IsBreaked( XBoxZone &zone, ENUM_X_PRICE priceType = X_PRICE_CLOSE // ) { // bool result = false; // // Validate ... result = zone.IsValid() && IsXValid(priceType); if (!result) { // result = true; return result; } // XOHCL iBar; double iPrice; bool isBullish; int start = zone.ToIndex(); int end = zone.FromIndex(); for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... iBar.Clean(); result = iBar.Init(zone.symbol, zone.period, i); if (!result) { // result = true; break; } // isBullish = zone.IsBullish(); iPrice = iBar.GetPrice(priceType); result = isBullish ? iPrice < zone.lower : iPrice > zone.upper; if (result) { break; } } // // Cleanup ... iBar.Clean(); // return result; } /** * Check Specified Bar is Acted On Specified Zone or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * @param validationLength: Specified Length for Breaks ... * * @return ( bool ) */ bool IsValidBreaked( XOHCL &bar, XBoxZone &zone, int validationLength = 3 // ) { // bool result = false; // // Normalize ... validationLength = NormalizeInt(validationLength, 1); // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // XOHCL iBar; int count = 0; int start = bar.Index(); int end = start + validationLength; for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... result = bar.BarAt(i, iBar); if (!result) { break; } // result = IsBreaked(iBar, zone); if (result) { count++; } } // result = IsValidSize(count) && count >= validationLength; // // Cleanup Resources ... iBar.Clean(); // return result; } /** * Check Specified Bar is Fake Breaked Specified Zone or not ... * * @param bar: Specified Bar ... * @param zone: Specified Zone ... * @param validationLength: Specified Length for Breaks ... * * @return ( bool ) */ bool IsFakeBreaked( XOHCL &bar, XBoxZone &zone, int validationLength = 3 // ) { // bool result = false; // // Normalize ... validationLength = NormalizeInt(validationLength, 1); // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // // Check Bar Must Acting Zone ... result = zone.IsBullish() ? bar.close > zone.upper : zone.IsBearish() ? bar.close < zone.lower : false; if (!result) { return result; } // // Detect Breaker Bars ... XOHCL breakerBars[]; int breakerBarsCount = GetBreakerBars( zone, breakerBars // ); result = IsValidSize(breakerBarsCount); if (!result) { // XClean(breakerBars); return result; } // // Get Youngest Breaker Bars ... int idx = GetYoungest(breakerBars); result = IsValidIndex(idx); if (!result) { // XClean(breakerBars); return result; } // result = breakerBars[idx].Index() - bar.Index() <= validationLength; // // Cleanup Resources ... XClean(breakerBars); // return result; } /** * Check Specified ZOne is Affected by Specified Bar or not ... * * @param bar: XOHCL, reference to Specified Bar ... * @param zone: XBoxZone, reference to Specified Zone ... * * @return ( bool ) */ bool IsZoneAffected( XOHCL &bar, XBoxZone &zone // ) { // bool result = false; // // Validate ... result = bar.IsValid() && zone.IsValid(); if (!result) { return result; } // bool isActed = IsActed(bar, zone); bool isTested = IsTested(bar, zone); bool isFakeBreaked = IsFakeBreaked(bar, zone); // result = isActed || isTested || isFakeBreaked; // return result; } // #endregion // #region Zones Hasers ... /** * Check a Bar is Inside a Zone or not ... * * @param index: int, reference to holds detected index ... * @param bar: reference to Specified Bar ... * @param source: reference collection to provide source ... * * @return ( bool ) */ bool HasInside( int &index, XOHCL &bar, XBoxZone &source[] // ) { // XBoxZone selected[]; int count = ExtractInsides(bar, selected, source); bool result = IsValidSize(count); if (result) { // index = GetYoungest(selected); if (IsValidIndex(index)) { result = FindIndex(index, selected[index], source); } } // XClean(selected); // return result; } /** * Check a Bar is Reject a Zone or not ... * * @param index: int, reference to holds detected index ... * @param bar: reference to Specified Bar ... * @param source: reference collection to provide source ... * * @return ( bool ) */ bool HasRejected( int &index, XOHCL &bar, XBoxZone &source[] // ) { // XBoxZone selected[]; int count = ExtractRejecteds(bar, selected, source); bool result = IsValidSize(count); if (result) { // index = GetYoungest(selected); if (IsValidIndex(index)) { result = FindIndex(index, selected[index], source); } } // XClean(selected); // return result; } /** * Check a Bar is Break a Zone or not ... * * @param index: int, reference to holds detected index ... * @param bar: reference to Specified Bar ... * @param source: reference collection to provide source ... * * @return ( bool ) */ bool HasBreaked( int &index, XOHCL &bar, XBoxZone &source[] // ) { // XBoxZone selected[]; int count = ExtractBreakeds(bar, selected, source); bool result = IsValidSize(count); if (result) { // index = GetYoungest(selected); if (IsValidIndex(index)) { result = FindIndex(index, selected[index], source); } } // XClean(selected); // return result; } /** * Check a Bar is Act a Zone or not ... * * @param index: int, reference to holds detected index ... * @param bar: reference to Specified Bar ... * @param source: reference collection to provide source ... * * @return ( bool ) */ bool HasActed( int &index, XOHCL &bar, XBoxZone &source[] // ) { // XBoxZone selected[]; int count = ExtractActeds(bar, selected, source); bool result = IsValidSize(count); if (result) { // index = GetYoungest(selected); if (IsValidIndex(index)) { result = FindIndex(index, selected[index], source); } } // XClean(selected); // return result; } // #endregion // #region Zone Extractors ... /** * Extract Affected Zones for Specified Bar ... * * @param bar: XOHCL, reference to Specified Bar ... * @param source: XBoxZone, reference collection to Provide Data Source ... * @param dest: XBoxZone, reference collection to holds result ... * @param forDir: ENUM_X_DIRECTION, Specified Zones Direction to Lookup ... * * @return ( int ) */ int ExtractAffectedZones( XOHCL &bar, XBoxZone &source[], XBoxZone &dest[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = bar.IsValid() && HasChild(source); if (!has) { return result; } // bool isActed; bool isTested; bool isInside; bool isFakeBreaked; for (int i = 0; i < ArraySize(source); i++) { // // Validate Direction ... has = !HasDirection(forDir) || forDir == source[i].dir; if (!has) { continue; } // // Check Affected ... isActed = IsActed(bar, source[i]); isTested = IsTested(bar, source[i]); isInside = IsInside(bar, source[i]); isFakeBreaked = IsFakeBreaked(bar, source[i]); // has = isActed || isTested || isInside || isFakeBreaked; if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all Items which Specified Bar is inside them ... * * @param bar: reference to Specified Bar ... * @param dest: reference to result ... * @param source: reference collection to provide source ... * * @return ( int ) */ int ExtractInsides( XOHCL &bar, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... bool has = bar.IsValid() && HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = IsInside( bar, source[i] // ); if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all Items which Specified Bar is Acted them ... * * @param bar: reference to Specified Bar ... * @param dest: reference to result ... * @param source: reference collection to provide source ... * * @return ( int ) */ int ExtractActeds( XOHCL &bar, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = bar.IsValid() && HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = IsActed( bar, source[i] // ); if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all Items which Specified Bar is Breaked them ... * * @param bar: reference to Specified Bar ... * @param dest: reference to result ... * @param source: reference collection to provide source ... * * @return ( int ) */ int ExtractBreakeds( XOHCL &bar, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... bool has = bar.IsValid() && HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = IsBreaked( bar, source[i] // ); if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Extract all Items which Specified Bar is Rejected them ... * * @param bar: reference to Specified Bar ... * @param dest: reference to result ... * @param source: reference collection to provide source ... * * @return ( int ) */ int ExtractRejecteds( XOHCL &bar, XBoxZone &dest[], XBoxZone &source[] // ) { // int result = 0; // // Prepare ... SpecifiedClean(dest); // // Validate ... bool has = bar.IsValid() && HasChild(source); if (!has) { return result; } // int count = ArraySize(source); for (int i = 0; i < count; i++) { // has = IsRejected( bar, source[i] // ); if (has) { // AddIfNotExists( source[i], dest // ); } } // result = ArraySize(dest); // return result; } /** * Collect all Bars which Breakes Specified Zone ... * * @param zone: reference to Specified Zone ... * @param dest: reference Collection to hold result ... * * @return ( int ) */ int GetBreakerBars( XBoxZone &zone, XOHCL &dest[] // ) { // int result = 0; // // Validate ... bool has = zone.IsValid(); if (!has) { return result; } // // Prepare ... SpecifiedClean(dest); // // Do Action ... XOHCL iBar; int start = zone.ToIndex(); int end = zone.FromIndex(); for (int i = start; i < end; i++) { // // Initialize indexed Bar ... has = iBar.Init( zone.symbol, zone.period, i // ); if (!has) { continue; } // has = IsBreaked( iBar, zone, false // Breakes by Close ... ); if (has) { // AddIfNotExists( iBar, dest // ); } // iBar.Clean(); } // result = ArraySize(dest); // iBar.Clean(); // return result; } /** * Collect all Bars which Inside Specified Zone ... * * @param zone: reference to Specified Zone ... * @param dest: reference Collection to hold result ... * * @return ( int ) */ int GetInsideBars( XBoxZone &zone, XOHCL &dest[] // ) { // int result = 0; // // Validate ... bool has = zone.IsValid(); if (!has) { return result; } // // Prepare ... SpecifiedClean(dest); // // Do Action ... XOHCL iBar; int start = zone.ToIndex(); int end = zone.FromIndex(); for (int i = start; i < end; i++) { // // Initialize indexed Bar ... has = iBar.Init( zone.symbol, zone.period, i // ); if (!has) { continue; } // has = IsInside( iBar, zone // ); if (has) { // AddIfNotExists( iBar, dest // ); } // iBar.Clean(); } // result = ArraySize(dest); // iBar.Clean(); // return result; } /** * Collect all Bars which Tested Specified Zone ... * * @param zone: reference to Specified Zone ... * @param dest: reference Collection to hold result ... * * @return ( int ) */ int GetTesterBars( XBoxZone &zone, XOHCL &dest[] // ) { // int result = 0; // // Validate ... bool has = zone.IsValid(); if (!has) { return result; } // // Prepare ... SpecifiedClean(dest); // // Do Action ... XOHCL iBar; int start = zone.ToIndex(); int end = zone.FromIndex(); for (int i = start; i < end; i++) { // // Initialize indexed Bar ... has = iBar.Init( zone.symbol, zone.period, i // ); if (!has) { continue; } // has = IsTested( iBar, zone // ); if (has) { // AddIfNotExists( iBar, dest // ); } // iBar.Clean(); } // result = ArraySize(dest); // iBar.Clean(); // return result; } /** * Validate Zones Range ... * * @param source: XBoxZone, collection reference to Validate ... * @param minAllowedRange: double, min allowed range to Validate ... * * @return ( int ) */ int ValidateZonesRange( XBoxZone &source[], double minAllowedRange // ) { // int result = 0; // // Validate ... bool has = HasChild(source) && minAllowedRange > 0; if (!has) { return result; } // XBoxZone iTMP; XBoxZone tmps[]; Copy(source, tmps); XClean(source); while (HasChild(tmps)) { // iTMP.Clean(); iTMP = tmps[0]; ArrayRemove(tmps, 0, 1); // // Check Range Validation ... has = iTMP.GetRange() > minAllowedRange; if (has) { AddIfNotExists(iTMP, source); } } // result = ArraySize(source); // // Cleanup ... XClean(tmps); iTMP.Clean(); // return result; } /** * Remove Breaked Zones ... * * @param source: XBoxZone, collection reference to Remove Breaked Zones ... * @param priceType: ENUM_X_PRICE, Specified Price type of Break Detection ... * * @return ( int ) */ int RemoveBreakedZones( XBoxZone &source[], ENUM_X_PRICE priceType = X_PRICE_CLOSE // ) { // int result = 0; // // Validate ... if (!HasChild(source) || !IsXValid(priceType)) { return result; } // XBoxZone tmp[]; Copy(source, tmp); XClean(source); XBoxZone iTMP; bool isBreaked = false; while (HasChild(tmp)) { // iTMP.Clean(); iTMP = tmp[0]; ArrayRemove(tmp, 0, 1); // isBreaked = IsBreaked(iTMP, priceType); if (!isBreaked) { // AddIfNotExists(iTMP, source); } } // result = ArraySize(source); // // Cleanup ... XClean(tmp); iTMP.Clean(); // return result; } // #endregion //+------------------------------------------------------------------+ // #region Bar Extensions ... /** * Check Specified Bar is Breaked or not ... * * @param bar: XOHCL, Specified Bar for Checking Proce ... * @param breakerBar: XOHCL, Hold's Breaker Bar if Exists ... * @param barIndex: int, Start Checking Bar till Bar's Index ... * @param breakDir: ENUM_X_DIRECTION, Checking Direction Type, if Bullish Break Price must bigger, otherwise must lower ... * @param barPriceType: ENUM_X_PRICE, Price type to Check Break ... * @param breakPriceType: ENUM_X_PRICE, Price Type to Break Bar's Price ... * * @return ( bool ) */ bool IsBarBreaked( XOHCL &bar, XOHCL &breakerBar, int barIndex = 0, ENUM_X_DIRECTION breakDir = X_DIRECTION_NONE, ENUM_X_PRICE barPriceType = X_PRICE_CLOSE, ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE // ) { // bool result = false; // // Normalize ... breakerBar.Clean(); if (barIndex < 0) { barIndex = 0; } // // Validate ... result = bar.IsValid() && HasDirection(breakDir) && IsXValid(barPriceType) && IsXValid(breakPriceType) && barIndex < bar.Index(); if (!result) { return result; } // // Loop for Validating ... XOHCL tmpBar; bool has = false; double tmpPrice = EMPTY_VALUE; double barPrice = bar.GetPrice(barPriceType); for (int i = barIndex; i < bar.Index(); i++) { // has = tmpBar.Init(bar.symbol, bar.period, i); if (!has) { continue; } // tmpPrice = tmpBar.GetPrice(breakPriceType); has = NotEmptyZero(tmpPrice); if (!has) { // tmpBar.Clean(); // continue; } // has = IsXBullish(breakDir) ? tmpPrice > barPrice : tmpPrice < barPrice; if (has) { // breakerBar = tmpBar; tmpBar.Clean(); break; } // tmpBar.Clean(); } // result = breakerBar.IsValid(); // return result; } // #endregion // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-poi.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XPOILib // Description: All models related to POIs ... // // // 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 "../Libraries/x-saherelm.common.lib.mq5" #include // // Definitions ... /** * All Available Market Patterns ... **/ enum ENUM_X_BAR_PATTERN { X_BAR_PATTERN_NONE = 0, X_BAR_PATTERN_HIGH = 1, X_BAR_PATTERN_LOW = 2, X_BAR_PATTERN_MOMENTUM = 3, X_BAR_PATTERN_ENGULFED = 4, X_BAR_PATTERN_TRUE_GAPED = 5, X_BAR_PATTERN_PINNED = 6, X_BAR_PATTERN_STAR = 7, X_BAR_PATTERN_PIERCING = 8, X_BAR_PATTERN_RISING = 9, X_BAR_PATTERN_FLAG = 10, X_BAR_PATTERN_SIGNALKEY = 11, X_BAR_PATTERN_OB = 12, X_BAR_PATTERN_FVG = 13, X_BAR_PATTERN_SUPPORT = 14, X_BAR_PATTERN_RESISTANCE = 15, X_BAR_PATTERN_PULLBACK = 16, X_BAR_PATTERN_CONSOLIDATION = 17, X_BAR_PATTERN_LEG = 18, }; /** * Validate an ENUM member ... * * @param value: ENUM_X_BAR_PATTERN ... * * @return ( bool ) */ bool IsXValid(ENUM_X_BAR_PATTERN value) { return value != X_BAR_PATTERN_NONE; } /** * Converts a Pattern ENUM to String Representation ... * * @param value: ENUM_X_BAR_PATTERN, member ... * * @return ( string ) */ string ToXString(ENUM_X_BAR_PATTERN value) { // string result = NULL; // switch (value) { // case X_BAR_PATTERN_NONE: result = "X_NONE"; break; // case X_BAR_PATTERN_HIGH: result = "XHIGHP"; break; // case X_BAR_PATTERN_LOW: result = "XLOWP"; break; // case X_BAR_PATTERN_MOMENTUM: result = "XMOMENTUMP"; break; // case X_BAR_PATTERN_ENGULFED: result = "XENGULFEDP"; break; // case X_BAR_PATTERN_TRUE_GAPED: result = "XGAPEDP"; break; // case X_BAR_PATTERN_PINNED: result = "XPINNEDP"; break; // case X_BAR_PATTERN_STAR: result = "XSTARP"; break; // case X_BAR_PATTERN_PIERCING: result = "XPIERCINGP"; break; // case X_BAR_PATTERN_RISING: result = "XRISINGP"; break; // case X_BAR_PATTERN_FLAG: result = "XFLAGP"; break; // case X_BAR_PATTERN_SIGNALKEY: result = "XSIGNALKEYP"; break; // case X_BAR_PATTERN_OB: result = "XOBP"; break; // case X_BAR_PATTERN_FVG: result = "XFVGP"; break; // case X_BAR_PATTERN_SUPPORT: result = "XSUPPORTP"; break; // case X_BAR_PATTERN_RESISTANCE: result = "XRESISTANCEP"; break; // case X_BAR_PATTERN_PULLBACK: result = "XPULLBACKP"; break; // case X_BAR_PATTERN_CONSOLIDATION: result = "XCONSOLIDATIONP"; break; // case X_BAR_PATTERN_LEG: result = "XLEGP"; break; } // return result; } /** * Parse an String Representation to it's Corresponding Bar Pattern ENUM ... * * @param value: string, provided pattern's string ... * * @return ( ENUM_X_BAR_PATTERN ) */ ENUM_X_BAR_PATTERN ToBarPattern(string value) { // ENUM_X_BAR_PATTERN result = X_BAR_PATTERN_NONE; // // Validate ... if (!IsXValid(value)) { return result; } // if (value == ToXString(X_BAR_PATTERN_NONE)) { result = X_BAR_PATTERN_NONE; } else if (value == ToXString(X_BAR_PATTERN_HIGH)) { result = X_BAR_PATTERN_HIGH; } else if (value == ToXString(X_BAR_PATTERN_LOW)) { result = X_BAR_PATTERN_LOW; } else if (value == ToXString(X_BAR_PATTERN_MOMENTUM)) { result = X_BAR_PATTERN_MOMENTUM; } else if (value == ToXString(X_BAR_PATTERN_ENGULFED)) { result = X_BAR_PATTERN_ENGULFED; } else if (value == ToXString(X_BAR_PATTERN_TRUE_GAPED)) { result = X_BAR_PATTERN_TRUE_GAPED; } else if (value == ToXString(X_BAR_PATTERN_PINNED)) { result = X_BAR_PATTERN_PINNED; } else if (value == ToXString(X_BAR_PATTERN_STAR)) { result = X_BAR_PATTERN_STAR; } else if (value == ToXString(X_BAR_PATTERN_PIERCING)) { result = X_BAR_PATTERN_PIERCING; } else if (value == ToXString(X_BAR_PATTERN_RISING)) { result = X_BAR_PATTERN_RISING; } else if (value == ToXString(X_BAR_PATTERN_FLAG)) { result = X_BAR_PATTERN_FLAG; } else if (value == ToXString(X_BAR_PATTERN_SIGNALKEY)) { result = X_BAR_PATTERN_SIGNALKEY; } else if (value == ToXString(X_BAR_PATTERN_OB)) { result = X_BAR_PATTERN_OB; } else if (value == ToXString(X_BAR_PATTERN_FVG)) { result = X_BAR_PATTERN_FVG; } else if (value == ToXString(X_BAR_PATTERN_SUPPORT)) { result = X_BAR_PATTERN_SUPPORT; } else if (value == ToXString(X_BAR_PATTERN_RESISTANCE)) { result = X_BAR_PATTERN_RESISTANCE; } else if (value == ToXString(X_BAR_PATTERN_PULLBACK)) { result = X_BAR_PATTERN_PULLBACK; } else if (value == ToXString(X_BAR_PATTERN_CONSOLIDATION)) { result = X_BAR_PATTERN_CONSOLIDATION; } else if (value == ToXString(X_BAR_PATTERN_LEG)) { result = X_BAR_PATTERN_LEG; } // return result; } /** * Get All Available Valid Bar Patterns ... * * @param dest: ENUM_X_BAR_PATTERN, reference collection to fill ... * * @return ( int ) */ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[]) { // XClean(dest); // Add(X_BAR_PATTERN_HIGH, dest); Add(X_BAR_PATTERN_LOW, dest); Add(X_BAR_PATTERN_MOMENTUM, dest); Add(X_BAR_PATTERN_ENGULFED, dest); Add(X_BAR_PATTERN_TRUE_GAPED, dest); Add(X_BAR_PATTERN_PINNED, dest); Add(X_BAR_PATTERN_STAR, dest); Add(X_BAR_PATTERN_PIERCING, dest); Add(X_BAR_PATTERN_RISING, dest); Add(X_BAR_PATTERN_FLAG, dest); Add(X_BAR_PATTERN_SIGNALKEY, dest); Add(X_BAR_PATTERN_OB, dest); Add(X_BAR_PATTERN_FVG, dest); Add(X_BAR_PATTERN_SUPPORT, dest); Add(X_BAR_PATTERN_RESISTANCE, dest); Add(X_BAR_PATTERN_PULLBACK, dest); Add(X_BAR_PATTERN_CONSOLIDATION, dest); Add(X_BAR_PATTERN_LEG, dest); // return ArraySize(dest); } /** * Get All Available Valid Bar Patterns ... * * @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill Patterns ... * @param dir: ENUM_X_DIRECTION, collection reference to Fill Directions ... * @param forDir: ENUM_X_DIRECTION, Force Patterns Direction ... * * @return ( int ) */ int GetAllBarPatters( ENUM_X_BAR_PATTERN &dest[], ENUM_X_DIRECTION &dir[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // XClean(dest); XClean(dir); // Add(X_BAR_PATTERN_HIGH, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_LOW, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_MOMENTUM, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_ENGULFED, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_TRUE_GAPED, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_PINNED, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_STAR, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_PIERCING, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_RISING, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_FLAG, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_SIGNALKEY, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_OB, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_FVG, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_SUPPORT, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_RESISTANCE, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_PULLBACK, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_CONSOLIDATION, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_LEG, dest); Add(forDir, dir); // return ArraySize(dest); } /** * Fill Required Candlestick Patters ... * * @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill ... * * @return ( int ) */ int GetCandlestickPatterns(ENUM_X_BAR_PATTERN &dest[]) { // int result = 0; // // Prepare ... XClean(dest); // Add(X_BAR_PATTERN_STAR, dest); Add(X_BAR_PATTERN_FLAG, dest); Add(X_BAR_PATTERN_PINNED, dest); Add(X_BAR_PATTERN_RISING, dest); Add(X_BAR_PATTERN_MOMENTUM, dest); Add(X_BAR_PATTERN_ENGULFED, dest); Add(X_BAR_PATTERN_PIERCING, dest); Add(X_BAR_PATTERN_SIGNALKEY, dest); Add(X_BAR_PATTERN_TRUE_GAPED, dest); // result = ArraySize(dest); // return result; } /** * Fill Required Candlestick Patters ... * * @param dest: ENUM_X_BAR_PATTERN, collection reference to Fill Patterns ... * @param dir: ENUM_X_DIRECTION, collection reference to Fill Directions ... * @param forDir: ENUM_X_DIRECTION, Force Patterns Direction ... * * @return ( int ) */ int GetCandlestickPatterns( ENUM_X_BAR_PATTERN &dest[], ENUM_X_DIRECTION &dir[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); XClean(dir); // Add(X_BAR_PATTERN_STAR, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_FLAG, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_PINNED, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_RISING, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_MOMENTUM, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_ENGULFED, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_PIERCING, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_SIGNALKEY, dest); Add(forDir, dir); // Add(X_BAR_PATTERN_TRUE_GAPED, dest); Add(forDir, dir); // result = ArraySize(dest); // return result; } // // Structures ... /** * Model a Trend Line ... **/ struct XTrend { // string symbol; datetime time; ENUM_TIMEFRAMES period; // double fromValue; datetime fromTime; // double toValue; datetime toTime; // ENUM_X_DIRECTION dir; // // Constructor ... XTrend() { Clean(); } // // Tools ... /** * Initialize ... * * @param _symbol: string, Specified Symbol ... * @param _period: ENUM_TIMEFRAMES, Specified Period ... * @param _time: datetime, Detection Time ... * @param _fromValue: double, From Value ... * @param _fromTime: datetime, From Time ... * @param _toValue: double, To Value ... * @param _toTime: datetime, To Time ... * * @return ( bool ) */ bool Init( string _symbol, ENUM_TIMEFRAMES _period, datetime _time, double _fromValue, datetime _fromTime, double _toValue, datetime _toTime // ) { // bool result = false; // time = _time; symbol = _symbol; period = _period; toTime = _toTime; toValue = _toValue; fromTime = _fromTime; fromValue = _fromValue; // result = IsValid(); if (!result) { Clean(); } // // Setting Direction ... if (result) { // dir = fromValue < toValue ? X_DIRECTION_BULLISH : fromValue > toValue ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // return result; } /** * Cleanup ... */ void Clean() { // time = NULL; toValue = 0; fromValue = 0; symbol = NULL; period = NULL; toTime = NULL; fromTime = NULL; dir = X_DIRECTION_NONE; // ZeroMemory(this); } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = IsXValid(time) && IsXValid(symbol) && IsXValid(period) && IsXValid(toTime) && IsXValid(fromTime) && NotEmptyZero(toValue) && NotEmptyZero(fromValue) && fromTime < toTime; // return result; } /** * Check Trend Has Specific Direction ... * * @return ( bool ) */ bool HasTrend() { return IsValid() && HasDirection(dir); } /** * Check Trend is Bullish ... * * @return ( bool ) */ bool IsBullish() { return HasTrend() && IsXBullish(dir); } /** * Check Trend is Bearish ... * * @return ( bool ) */ bool IsBearish() { return HasTrend() && IsXBearish(dir); } /** * Get Unique Identifier ... * * @return ( string ) */ string GetObjectID() { // string result = NULL; // if (IsValid()) { double ifv = NormalizePrice(fromValue, symbol); result = "XTRND_" + ToXString(dir) + "_" + ToXString(ifv) + "_" + ToXString(TimeToSeconds(fromTime)); } // return result; } }; /** * Represent a Pivot ... **/ struct XPivot { // // Props ... double value; // Value datetime time; // Time string symbol; // Symbol ENUM_X_DIRECTION dir; // Direction ENUM_TIMEFRAMES period; // Period ENUM_X_PIVOT_TYPE type; // Type // string prefix; // Object Prefix // // Constructor ... XPivot() { Clean(); } // // Init ... /** * Initialize Structure ... * * @param _value: double, value of point ... * @param _time: datetime, time of point ... * @param _symbol: string, Symbol ... * @param _dir: ENUM_X_DIRECTION, direction of point ... * @param _period: ENUM_TIMEFRAMES, period ... * @param _type: ENUM_X_PIVOT_TYPE, point type ... * * @return ( bool ) */ bool Init( double _value, datetime _time, string _symbol, ENUM_X_DIRECTION _dir, ENUM_TIMEFRAMES _period, ENUM_X_PIVOT_TYPE _type // ) { // bool result = false; // dir = _dir; time = _time; type = _type; value = _value; symbol = _symbol; period = _period; // result = IsValid(); if (!result) { Clean(); } // return result; } // // Tools ... /** * Cleanup Model ... */ void Clean() { // value = 0; time = NULL; symbol = NULL; period = NULL; prefix = NULL; dir = X_DIRECTION_NONE; type = X_PIVOT_TYPE_NONE; // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = value > 0 && IsXValid(type) && HasDirection(dir) && IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period); // return result; } /** * Check Model is Peak or not ... * * @return ( bool ) */ bool IsPeak() { // bool result = false; // result = IsValid() && IsXPeak(type); // return result; } /** * Check Model is Vale or not ... * * @return ( bool ) */ bool IsVale() { // bool result = false; // result = IsValid() && IsXVale(type); // return result; } /** * Check Point is Bullish or not ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = IsValid() && IsSpecifiedBullish(dir); // return result; } /** * Check Point is Bearish or not ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = IsValid() && IsSpecifiedBearish(dir); // return result; } /** * Check two Struct are Same or not ... * * @param item: XPivot ... * * @return ( bool ) */ bool IsSameAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && dir == item.dir && type == item.type && time == item.time && value == item.value && symbol == item.symbol && period == item.period; // if (result && IsXValid(prefix)) { // result = result && prefix == item.prefix; } // return result; } /** * Calculate Pivot Age ... * * @return ( int ) */ int GetAge() { // int result = -1; // if (!IsValid()) { return result; } // result = GetBarIndex( symbol, period, time // ); // return result; } /** * Get Pivot Time Bar ... * * @param bar: XOHCL, reference to hold result ... * * @return ( bool ) */ bool GetBar(XOHCL &bar) { // bool result = false; // // Prepare ... bar.Clean(); // // Validate ... result = IsValid(); if (!result) { return result; } // // Initial Bar ... result = bar.Init( symbol, period, time // ); // if (!result) { bar.Clean(); } // return result; } /** * Check to model Has Same Symbol ... * * @param item: XPivot, dest model for Checking ... * * @return ( bool ) */ bool IsSameSymbolAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && symbol == item.symbol; // return result; } /** * Check to model Has Same Period ... * * @param item: XPivot, dest model for Checking ... * * @return ( bool ) */ bool IsSamePeriodAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && period == item.period; // return result; } /** * Check to model Has Same Symbol/Period ... * * @param item: XPivot, dest model for Checking ... * * @return ( bool ) */ bool IsSameMarketAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameSymbolAs(item) && IsSamePeriodAs(item); // return result; } /** * Check to model Has Same Type ... * * @param item: XPivot, dest model for Checking ... * * @return ( bool ) */ bool IsSameTypeAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && type == item.type; // return result; } /** * Check to model Has Same Direction ... * * @param item: XPivot, dest model for Checking ... * * @return ( bool ) */ bool IsSameDirectionAs(XPivot &item) { // bool result = false; // result = IsValid() && item.IsValid() && dir == item.dir; // return result; } // // Logging Tools ... /** * Extract Specified Token of Struct ... * * @return ( string ) */ string GetTag() { // string result = NULL; // string token = GetToken(this); // result = (IsSpecifiedValid(prefix) ? prefix + "_" : "") + token; // return result; } /** * Represent an String Unique Identifier for Chart Objects ... * * @return ( string ) */ string GetObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(dir) + "_" + ToXString(type) + "_" + ToXString(TimeToSeconds(time)); // return result; } /** * Represent a Point as String ... * * @param spacer: string, How to Represent Spaces ... * * @return ( string ) */ string GetMessage(string spacer = NULL) { // string result = ""; // // Normalize Spacer ... if (!IsSpecifiedValid(spacer)) { spacer = " "; } // // Validate ... if (!IsValid()) { return result; } // result = ToXString(dir) + spacer + GetTag() + ":" + spacer + "Symbol: " + symbol + spacer + "Period: " + ToXString(period) + spacer + "Type: " + ToXString(type) + spacer + "Direction: " + ToXString(dir) + spacer + "Value: " + ToXString(value) + spacer + "Time: " + ToXString(time) + spacer; // return result; } }; /** * Model a Box ... **/ struct XBoxZone { // // Props ... string symbol; ENUM_TIMEFRAMES period; // double upper; double lower; // datetime at; datetime from; datetime to; // string type; ENUM_X_DIRECTION dir; // // Special Props ... datetime breakAt; datetime tests[]; datetime acteds[]; datetime breaks[]; datetime insides[]; datetime refines[]; datetime fakeBreaks[]; // // Constructor ... XBoxZone() { Clean(); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // upper = 0; lower = 0; to = NULL; at = NULL; from = NULL; symbol = NULL; period = NULL; dir = X_DIRECTION_NONE; // SpecialClean(); // ZeroMemory(this); } bool Init( string _symbol, ENUM_TIMEFRAMES _period, double _upper, double _lower, datetime _from, datetime _to, ENUM_X_DIRECTION _dir, string _type = "", datetime _at = NULL // ) { // bool result = false; // // Validate ... result = IsXValid(_symbol) && IsXValid(_period) && _upper > 0 && _lower > 0 && _upper > _lower && IsXValid(_from) && IsXValid(_to) && _from < _to && HasDirection(_dir); if (!result) { return result; } // this.to = _to; this.at = _at; this.dir = _dir; this.from = _from; this.type = _type; this.lower = _lower; this.upper = _upper; this.symbol = _symbol; this.period = _period; // result = IsValid(); if (!result) { Clean(); } // return result; } /** * Clean Special Props ... */ void SpecialClean() { // breakAt = NULL; XClean(tests); XClean(acteds); XClean(breaks); XClean(insides); XClean(refines); XClean(fakeBreaks); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // upper > 0 && lower > 0 && from < to && IsSpecifiedValid(to) && upper >= lower && IsSpecifiedValid(from) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period) // ; // return result; } /** * Check Box is Bullish or not ... * * @return ( bool ) */ bool IsBullish() { return IsValid() && IsSpecifiedBullish(dir); } /** * Check Box is Bearish or not ... * * @return ( bool ) */ bool IsBearish() { return IsValid() && IsSpecifiedBearish(dir); } /** * Clone Box by Provided Source ... * * @return ( bool ) */ bool Clone(XBoxZone &source) { // bool result = false; // Clean(); result = source.IsValid(); if (!result) { return result; } // // Filling Props ... to = source.to; dir = source.dir; from = source.from; type = source.type; upper = source.upper; lower = source.lower; symbol = source.symbol; period = source.period; // result = IsValid(); if (!result) { Clean(); } // return result; } /** * Check Box is Same as Other ... * * @param item: XBoxZone instance Resource ... * * @return ( bool ) */ bool IsSameAs(XBoxZone &item) { // return IsValid() && item.IsValid() && dir == item.dir && from == item.from && type == item.type && lower == item.lower && upper == item.upper && symbol == item.symbol && period == item.period; } /** * Retrieve Box Age ... * * @param forPeriod: ENUM_TIMEFRAMES member ... * * @return ( int ) */ int GetAge( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = 0; // if (!IsValid()) { return result; } // if (!IsSpecifiedValid(forPeriod)) { forPeriod = period; } // result = iBarShift( symbol, forPeriod, from // ); // return result; } /** * Calculate Box Middle Price ... * * @return ( double ) */ double GetMid() { // double result = 0; // if (!IsValid()) { return result; } // double diffAvg = (upper - lower) / 2; result = lower + diffAvg; result = NormalizePrice(result, symbol); // return result; } /** * Calculate Box Leg N Price ... * N default is 2 * * @param leg: int ... * * @return ( double ) */ double GetLeg(int leg = 2) { // double result = 0; // leg = NormalizeInt(leg, 2); // if (!IsValid()) { return result; } // double range = (upper - lower) * leg; result = IsBullish() ? upper + range : lower - range; result = NormalizePrice(result, symbol); // return result; } /** * Calculate Box Range ... * * @return ( double ) */ double GetRange() { // double result = 0; // if (!IsValid()) { return result; } // result = (upper - lower); result = NormalizePrice(result, symbol); // return result; } /** * Retrieve Box Applied Price ... * * @return ( double ) */ double GetDirectionalPrice() { // double result = 0; // if (!IsValid()) { return result; } // result = IsBullish() ? upper : lower; // return result; } /** * Retrieve Box Breaked Price ... * * @return ( double ) */ double GetInDirectionalPrice() { // double result = 0; // if (!IsValid()) { return result; } // result = IsBullish() ? lower : upper; // return result; } /** * To Bar Index ... * * @return ( int ) */ int ToIndex( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = -1; // if (!IsValid()) { return result; } // if (!IsSpecifiedValid(forPeriod)) { forPeriod = period; } // result = GetBarIndex( symbol, forPeriod, to // ); // return result; } /** * Retrieve To Bar ... * * @return ( bool ) */ bool ToBar(XOHCL &bar) { // bool result = false; // bar.Clean(); // int idx = ToIndex(); // result = IsValid() && IsValidIndex(idx); if (!result) { return result; } // result = bar.Init( symbol, period, idx // ); // return result; } /** * At Bar Index ... * * @return ( int ) */ int AtIndex( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = -1; // if (!IsValid() || !IsXValid(at)) { return result; } // if (!IsSpecifiedValid(forPeriod)) { forPeriod = period; } // result = GetBarIndex( symbol, forPeriod, at // ); // return result; } /** * Retrieve At Bar ... * * @return ( bool ) */ bool AtBar(XOHCL &bar) { // bool result = false; // bar.Clean(); // int idx = AtIndex(); // result = IsValid() && IsValidIndex(idx); if (!result) { return result; } // result = bar.Init( symbol, period, idx // ); // return result; } /** * From Bar Index ... * * @return ( int ) */ int FromIndex( ENUM_TIMEFRAMES forPeriod = NULL // ) { // int result = -1; // if (!IsValid()) { return result; } // if (!IsSpecifiedValid(forPeriod)) { forPeriod = period; } // result = GetBarIndex( symbol, forPeriod, from // ); // return result; } /** * Retrieve From Bar ... * * @return ( bool ) */ bool FromBar(XOHCL &bar) { // bool result = false; // bar.Clean(); // int idx = FromIndex(); // result = IsValid() && IsValidIndex(idx); if (!result) { return result; } // result = bar.Init( symbol, period, idx // ); // return result; } /** * Retrieve Unique Identifier ... * * @return ( string ) */ string GetTag() { // int digits = GetDigits(symbol); double nUpper = NormalizeDouble(NormalizePrice(upper, symbol), digits); double nLower = NormalizeDouble(NormalizePrice(lower, symbol), digits); // string typeStr = IsSpecifiedValid(type) ? type : "XBOX"; string result = // typeStr + "_" + ToString(dir) + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(nUpper) + "_" + ToXString(nLower) // ; // return result; } /** * Retrieve Unique Middle Identifier ... * * @return ( string ) */ string GetMiddleTag() { // int digits = GetDigits(symbol); double nMid = NormalizeDouble(NormalizePrice(GetMid(), symbol), digits); // string typeStr = IsSpecifiedValid(type) ? type : "XBOX"; string result = // typeStr + "_" + "Mid_" + ToString(dir) + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(nMid) // ; // return result; } }; /** * Model a Direction Shift ... **/ struct XDirectionShift { // // Props ... string type; datetime at; double after; double before; string symbol; ENUM_TIMEFRAMES period; ENUM_X_DIRECTION shiftTo; // // Constructor ... XDirectionShift() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // at = NULL; after = 0; before = 0; type = NULL; symbol = NULL; period = NULL; shiftTo = X_DIRECTION_NONE; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = after > 0 && IsSpecifiedValid(at) && IsSpecifiedValid(type) && after != before && IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && HasDirection(shiftTo); // return result; } // bool Init( string _type, datetime _at, double _after, double _before, string _symbol, ENUM_TIMEFRAMES _period, ENUM_X_DIRECTION _shiftTo // ) { // bool result = false; // // Validate ... result = IsXValid(_at) && IsXValid(_type) && IsXValid(_symbol) && IsXValid(_period) && NotEmptyZero(_after) && NotEmptyZero(_before) && HasDirection(_shiftTo); if (!result) { return result; } // type = _type; at = _at; after = _after; before = _before; symbol = _symbol; period = _period; shiftTo = _shiftTo; // result = IsValid(); // return result; } // // Get Bar Index of Direction Shift ... int Index() { // int result = -1; // // Validate ... if (!IsValid()) { return result; } // // Retrieve Bar Index ... result = GetBarIndex( symbol, period, at // ); // return result; } // // Get At Bar ... bool AtBar(XOHCL &bar) { // bool result = false; // // Normalize ... bar.Clean(); // // Validate ... result = IsValid(); if (!result) { return result; } // int idx = Index(); if (IsValidIndex(idx)) { // result = bar.Init( symbol, period, idx // ); } // result = bar.IsValid(); // return result; } // // Check Same ... bool IsSameAs(XDirectionShift &item) { // bool result = false; // result = IsValid() && item.IsValid(); if (!result) { return result; } // result = // at == item.at && type == item.type && after == item.after && before == item.before && symbol == item.symbol && period == item.period && shiftTo == item.shiftTo // ; // return result; } }; /** * Configure Draws ... **/ struct XPOIDrawConfig { // // Props ... // color bullishColor; color bearishColor; color neuturalColor; // int arrowsWidth; int bullishArrow; int bearishArrow; int arrowsThreshold; ENUM_X_PRICE arrowsValePriceType; ENUM_X_PRICE arrowsPeakPriceType; // int zonesWidth; bool zonesFill; bool ignoreZonesAt; ENUM_LINE_STYLE zonesStyle; // int trendWidth; bool trendRayLeft; bool trendRayRight; ENUM_LINE_STYLE trendStyle; // // Constructor ... XPOIDrawConfig() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // bullishColor = CLR_NONE; bearishColor = CLR_NONE; neuturalColor = CLR_NONE; // arrowsWidth = 0; bullishArrow = 0; bearishArrow = 0; arrowsThreshold = 0; arrowsValePriceType = X_PRICE_NONE; arrowsPeakPriceType = X_PRICE_NONE; // zonesWidth = 1; zonesFill = false; ignoreZonesAt = true; zonesStyle = STYLE_SOLID; // trendWidth = 0; trendRayLeft = false; trendRayRight = false; trendStyle = STYLE_DOT; } /** * Default Config ... */ void Default() { // bullishColor = clrAqua; bearishColor = clrMagenta; neuturalColor = clrGray; // arrowsWidth = 1; bullishArrow = 159; bearishArrow = 159; arrowsThreshold = 5; arrowsValePriceType = X_PRICE_LOW; arrowsPeakPriceType = X_PRICE_HIGH; // zonesWidth = 1; zonesFill = true; ignoreZonesAt = true; zonesStyle = STYLE_SOLID; // trendWidth = 2; trendRayLeft = false; trendRayRight = true; trendStyle = STYLE_DOT; } // }; // ### FILE: C:\Users\SaherElm\AppData\Roaming\MetaQuotes\Terminal\572C4A1F743028C65C8BA0B780030F0D\MQL5\Libraries\x-saherelm.x-trade.lib.mq5 /////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XTradeLib // Description: All models related to Trade ... // // // 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 "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-guard.lib.mq5" #include // // Definitions ... // // a List of Used Tokens ... // // Common ... string XIDToken = "ID"; string XTicketToken = "TK"; string XModeToken = "MD"; string XTypeToken = "TY"; string XPeriodToken = "PR"; string XProviderToken = "PRV"; string XProfitToken = "PF"; // string XTPToken = "TP"; string XSLToken = "SL"; string XTimeToken = "TM"; string XEntryToken = "EN"; string XVolumeToken = "VL"; string XSymbolToken = "SMBL"; // string XSupportToken = "SP"; string XEQMSupportToken = "EQM"; string XEQPToken = "EQP"; // string XSLTrailToken = "SLT"; // string XActionToken = "A"; // string XDirectionalToken = "D"; string XINDirectionalToken = "IND"; // string XRecoveryToken = "XRCV"; // // Available Order Modes ... enum ENUM_X_ORDER_MODES { X_ORDER_MODE_NOTHING, // Nothing X_ORDER_MODE_MARKET, // Market Order X_ORDER_MODE_STOP, // Pending Stop Order X_ORDER_MODE_LIMIT, // Pending Limit Order X_ORDER_MODE_STOP_LIMIT, // Pending Stop Limit Order }; // string ToString(ENUM_X_ORDER_MODES value) { // string result = NULL; // switch (value) { // case X_ORDER_MODE_MARKET: result = "Market"; break; // case X_ORDER_MODE_LIMIT: result = "Limit"; break; // case X_ORDER_MODE_STOP: result = "Stop"; break; // case X_ORDER_MODE_STOP_LIMIT: result = "StopLimit"; break; } // return result; } // // Select Positions Type ... enum ENUM_X_POSITION_SELECT_METHODS { X_POSITION_SELECT_NONE, // None X_POSITION_SELECT_MAX, // Max X_POSITION_SELECT_MIN, // Min X_POSITION_SELECT_BOTH, // Min and Max X_POSITION_SELECT_ALL, // All }; // // Signal Execution Result ... // note that some of them must be handles in // EA's ... enum ENUM_X_SIGNAL_EXECUTION_RESULT { // X_SIGNAL_EXECUTION_UNKNOWN, // Unknown X_SIGNAL_EXECUTION_SUCCEED, // Succed X_SIGNAL_EXECUTION_FAILED_SPREAD, // Spread more than Max Allowed X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED, // Not Allowed Trade Type X_SIGNAL_EXECUTION_FAILED_NO_EQUITY, // No Equity for Trade X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR, // Price Error X_SIGNAL_EXECUTION_FAILED_PREV_PROFIT_ERROR, // Prev Profit Error X_SIGNAL_EXECUTION_FAILED_MAX_REACHED, // Max Allowed Positions Reached X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED, // Same Positions Delay Not Passed X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS, // Invalid Params }; // enum ENUM_X_POSITION_TYPES { X_POSITION_TYPE_NONE = 0, X_POSITION_TYPE_ALL = 1, X_POSITION_TYPE_LONG = 2, X_POSITION_TYPE_SHORT = 3, }; // bool IsValid(ENUM_X_POSITION_TYPES value) { return value != X_POSITION_TYPE_NONE; } bool IsXValid(ENUM_X_POSITION_TYPES value) { return IsValid(value); } // bool HasSpecifiedType(ENUM_X_POSITION_TYPES value) { // return value == X_POSITION_TYPE_LONG || value == X_POSITION_TYPE_SHORT; } // string ToString(ENUM_X_POSITION_TYPES value) { // string result = NULL; // switch (value) { // case X_POSITION_TYPE_ALL: result = "All"; break; // case X_POSITION_TYPE_NONE: result = "NONE"; break; // case X_POSITION_TYPE_SHORT: result = "Short"; break; // case X_POSITION_TYPE_LONG: result = "Long"; break; } // return result; } string ToXString(ENUM_X_POSITION_TYPES value) { return ToString(value); } // bool IsLong(ENUM_X_POSITION_TYPES value) { return value == X_POSITION_TYPE_LONG; } // bool IsShort(ENUM_X_POSITION_TYPES value) { return value == X_POSITION_TYPE_SHORT; } // bool ToPositionType( ENUM_POSITION_TYPE &dest, ENUM_X_POSITION_TYPES source // ) { // bool result = false; // result = source == X_POSITION_TYPE_LONG || source == X_POSITION_TYPE_SHORT; if (!result) { return result; } // dest = source == X_POSITION_TYPE_LONG ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; // return result; } // ENUM_X_POSITION_TYPES ToPositionType(ENUM_POSITION_TYPE value) { return IsLong(value) ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; } // ENUM_X_POSITION_TYPES OppositPositionType(ENUM_POSITION_TYPE type) { // ENUM_X_POSITION_TYPES result = X_POSITION_TYPE_NONE; // bool isLong = IsLong(type); bool isShort = IsShort(type); // result = // isLong ? X_POSITION_TYPE_SHORT : isShort ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_NONE // ; // return result; } // ENUM_X_DIRECTION ToDirection(ENUM_POSITION_TYPE value) { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // result = IsLong(value) ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // ENUM_X_DIRECTION ToDirection(ENUM_X_POSITION_TYPES value) { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // result = value == X_POSITION_TYPE_ALL ? X_DIRECTION_ALL : value == X_POSITION_TYPE_LONG ? X_DIRECTION_BULLISH : value == X_POSITION_TYPE_SHORT ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; // return result; } // // All Awailable Trade Restrictions ... enum ENUM_XTRADE_RESTRICTION_PERIOD { XTRADE_RESTRICATION_NONE, // None XTRADE_RESTRICATION_HOURLY, // Per Hour XTRADE_RESTRICATION_DAILY, // Per Day XTRADE_RESTRICATION_WEEKLY, // Per Week XTRADE_RESTRICATION_MONTHLY, // Per Month }; // string ToXString(ENUM_XTRADE_RESTRICTION_PERIOD value) { // string result = NULL; // result = EnumToString(value); // return result; } // ENUM_XTRADE_RESTRICTION_PERIOD ToXRestrictionPeriod(string value) { // ENUM_XTRADE_RESTRICTION_PERIOD result = XTRADE_RESTRICATION_NONE; // if (!IsSpecifiedValid(value)) { return result; } // // None ... if (value == ToXString(XTRADE_RESTRICATION_NONE)) { result = XTRADE_RESTRICATION_NONE; } // // Per Hour ... else if (value == ToXString(XTRADE_RESTRICATION_HOURLY)) { result = XTRADE_RESTRICATION_HOURLY; } // // Per Day ... else if (value == ToXString(XTRADE_RESTRICATION_DAILY)) { result = XTRADE_RESTRICATION_DAILY; } // // Per Week ... else if (value == ToXString(XTRADE_RESTRICATION_WEEKLY)) { result = XTRADE_RESTRICATION_WEEKLY; } // // Per Month ... else if (value == ToXString(XTRADE_RESTRICATION_MONTHLY)) { result = XTRADE_RESTRICATION_MONTHLY; } // return result; } // int GetXRestrictionsPeriodSeconds(ENUM_XTRADE_RESTRICTION_PERIOD value) { // int result = 0; // if (!HasRestrictions(value)) { return result; } // switch (value) { // // None ... case XTRADE_RESTRICATION_NONE: result = 0; break; // // Hour ... case XTRADE_RESTRICATION_HOURLY: result = PeriodSeconds(PERIOD_H1); break; // // Dayly ... case XTRADE_RESTRICATION_DAILY: result = PeriodSeconds(PERIOD_D1); break; // // Weekly ... case XTRADE_RESTRICATION_WEEKLY: result = PeriodSeconds(PERIOD_W1); break; // // Monthly ... case XTRADE_RESTRICATION_MONTHLY: result = PeriodSeconds(PERIOD_M1); break; } // return result; } /** * Check a Value Has Trade Restrictions or not ... * * @param value: ENUM_XTRADE_RESTRICTION_PERIOD * Ù‘ * @return ( bool ) */ bool HasRestrictions(ENUM_XTRADE_RESTRICTION_PERIOD value) { return value != XTRADE_RESTRICATION_NONE; } // // All Awailable Trade Finalizations ... enum ENUM_XTRADE_FINALIZATION { XTRADE_FINAL_NONE, // None XTRADE_FINAL_TP, // TP XTRADE_FINAL_SL, // SL XTRADE_FINAL_CLOSE_IN_PROFIT, // Profit XTRADE_FINAL_CLOSE_IN_LOSE, // Lost }; // string ToXString(ENUM_XTRADE_FINALIZATION value) { return EnumToString(value); } // // Position Selecting Methods ... enum ENUM_XPOSITION_SELECT_TYPES { XPOSITION_SELECT_NONE = 0, // None XPOSITION_SELECT_ALL = 1, // All XPOSITION_SELECT_IN_PROFITS = 2, // In Profit Positions XPOSITION_SELECT_IN_DRAWDOWNS = 3, // In Drawdown Positions XPOSITION_SELECT_OLDEST = 4, // Oldest Position XPOSITION_SELECT_YOUNGEST = 5, // Youngest Position XPOSITION_SELECT_IN_PROFITS_OLDEST = 6, // In Profit Positions Oldest one XPOSITION_SELECT_IN_PROFITS_YOUNGEST = 7, // In Profit Positions Youngest one XPOSITION_SELECT_IN_PROFITS_MIN = 8, // Minimum Profitable Position XPOSITION_SELECT_IN_PROFITS_MAX = 9, // Maximum Profitable Position XPOSITION_SELECT_IN_DRAWDOWN_OLDEST = 10, // In Drawdown Positions Oldest one XPOSITION_SELECT_IN_DRAWDOWN_YOUNGEST = 11, // In Drawdown Positions Youngest one XPOSITION_SELECT_IN_DRAWDOWN_MIN = 12, // Minimum in Drawdown Position XPOSITION_SELECT_IN_DRAWDOWN_MAX = 13, // Maximum in Drawdown Position XPOSITION_SELECT_SAMES = 14, // Same Type Positions XPOSITION_SELECT_SAMES_OLDEST = 15, // Same Type Positions Oldest one XPOSITION_SELECT_SAMES_YOUNGEST = 16, // Same Type Positions Youngest one XPOSITION_SELECT_OPPOSITS = 17, // Opposit Type Positions XPOSITION_SELECT_OPPOSIT_OLDEST = 18, // Opposit Type Positions Oldest one XPOSITION_SELECT_OPPOSIT_YOUNGEST = 19, // Opposit Type Positions Youngest one XPOSITION_SELECT_SAME_IN_PROFITS = 20, // Same Type In Profit Positions XPOSITION_SELECT_SAME_IN_PROFITS_OLDEST = 21, // Same Type In Profit Positions Oldest one XPOSITION_SELECT_SAME_IN_PROFITS_YOUNGEST = 22, // Same Type In Profit Positions Youngest one XPOSITION_SELECT_SAME_IN_PROFITS_MIN = 23, // Minimum Profitable of Same Type Positions XPOSITION_SELECT_SAME_IN_PROFITS_MAX = 24, // Maximum Profitable of Same Type Positions XPOSITION_SELECT_OPPOSIT_IN_PROFITS = 25, // Opposit Type In Profit Positions XPOSITION_SELECT_OPPOSIT_IN_PROFITS_OLDEST = 26, // Opposit Type In Profit Positions Oldest one XPOSITION_SELECT_OPPOSIT_IN_PROFITS_YOUNGEST = 27, // Opposit Type In Profit Positions Youngest one XPOSITION_SELECT_OPPOSIT_IN_PROFITS_MIN = 28, // Minimum Profitable of Opposit Type Positions XPOSITION_SELECT_OPPOSIT_IN_PROFITS_MAX = 29, // Maximum Profitable of Opposit Type Positions XPOSITION_SELECT_SAME_IN_DRAWDOWNS = 30, // Same Type In Deawdown Positions XPOSITION_SELECT_SAME_IN_DRAWDOWN_OLDEST = 31, // Same Type In Deawdown Positions Oldest one XPOSITION_SELECT_SAME_IN_DRAWDOWN_YOUNGEST = 32, // Same Type In Deawdown Positions Youngest one XPOSITION_SELECT_SAME_IN_DRAWDOWN_MIN = 33, // Minimum In Drawdown of Same Type Positions XPOSITION_SELECT_SAME_IN_DRAWDOWN_MAX = 34, // Maximum In Drawdown of Same Type Positions XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWNS = 35, // Opposit Type In Deawdown Positions XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_OLDEST = 36, // Opposit Type In Deawdown Positions Oldest one XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_YOUNGEST = 37, // Opposit Type In Deawdown Positions Youngest one XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MIN = 38, // Minimum In Drawdown of Opposit Type Positions XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MAX = 39, // Maximum In Drawdown of Opposit Type Positions }; /** * Validate Position Select Type ... * * @param value: ENUM_XPOSITION_SELECT_TYPES * * @return ( bool ) */ bool IsXValid(ENUM_XPOSITION_SELECT_TYPES value) { return value != XPOSITION_SELECT_NONE; } // string ToXString(ENUM_XPOSITION_SELECT_TYPES value) { return EnumToString(value); } // // Structs ... // struct XRR { // double tps[]; // double sl; double entry; // string prefix; string symbol; datetime time; ENUM_TIMEFRAMES period; // ENUM_X_POSITION_TYPES type; // // Constructor ... XRR() { Clean(); } // // Tools ... // void Clean() { // sl = 0; entry = 0; // time = NULL; prefix = NULL; period = NULL; symbol = NULL; // type = X_POSITION_TYPE_NONE; // SpecifiedClean(tps); // ZeroMemory(this); } // bool Init( string _symbol, ENUM_TIMEFRAMES _period, double _sl, double _entry, ENUM_X_POSITION_TYPES _type, string _prefix = NULL // ) { // bool result = false; // result = _sl > 0 && _entry > 0 && IsSpecifiedValid(_symbol) && IsSpecifiedValid(_period) && _type != X_POSITION_TYPE_ALL && _type != X_POSITION_TYPE_NONE && (_type == X_POSITION_TYPE_LONG ? _entry > _sl : _entry < _sl); if (!result) { return result; } // Default(); // sl = _sl; type = _type; entry = _entry; symbol = _symbol; period = _period; prefix = _prefix; // time = TimeCurrent(); // result = IsValid(); // return result; } // void Default() { // Add( 1.0, tps // ); Add( 1.5, tps // ); Add( 2.0, tps // ); Add( 3.0, tps // ); Add( 4.0, tps // ); Add( 5.0, tps // ); Add( 6.0, tps // ); } // bool IsValid() { // bool result = false; // result = sl > 0 && entry > 0 && IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && IsValidSize(ArraySize(tps)) && type != X_POSITION_TYPE_ALL && type != X_POSITION_TYPE_NONE && (type == X_POSITION_TYPE_LONG ? entry > 0 : entry < sl); // return result; } // string GetTag() { // string result = NULL; // if (!IsValid()) { // result = GetTypeName(this); return result; } // string sep = "_"; // result = GetTypeName(this) + sep + (IsSpecifiedValid(prefix) ? prefix + sep : "") + symbol + sep + ToXString(period) + sep + ToFormatString(time) + sep + ToString(type); // return result; } }; // // Model a Target ... struct XTarget { // // Props ... bool doRF; // Do RF on Target bool doRFOnEntry; // Do RF on Entry double actingDistance; // Acting Distances double target; // Target Price for Actions double volumeMultiplier; // Volume Multiplier for Partial Close double tpValue; // TP Value Changed ... // // Constructor ... XTarget() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // target = 0; tpValue = 0; doRF = false; actingDistance = 0; doRFOnEntry = false; volumeMultiplier = 0; } // // Validate ... bool IsValid() { // bool result = false; // result = target > 0; // return result; } }; // // Get Lowest Target index ... int GetLowest(XTarget &targets[]) { // int result = -1; // if (!HasChild(targets)) { return result; } // XTarget iTarget; int count = ArraySize(targets); for (int i = 0; i < count; i++) { // bool canSet = !iTarget.IsValid() ? true : iTarget.target > targets[i].target; if (canSet) { // result = i; iTarget = targets[i]; } } // iTarget.Clean(); // return result; } // // Get Highest Target index ... int GetHighest(XTarget &targets[]) { // int result = -1; // if (!HasChild(targets)) { return result; } // XTarget iTarget; int count = ArraySize(targets); for (int i = 0; i < count; i++) { // bool canSet = !iTarget.IsValid() ? true : iTarget.target < targets[i].target; if (canSet) { // result = i; iTarget = targets[i]; } } // iTarget.Clean(); // return result; } // // Apply Sorting on Targets ... void ApplySortOnTargets( ENUM_X_DIRECTION forDir, // Target Sorting Direction ... XTarget &targets[] // Targets to Apply Sorting ... ) { // bool has = HasChild(targets) && HasDirection(forDir); if (!has) { return; } // bool isBullish = IsBullish(forDir); bool isBearish = IsBearish(forDir); // XTarget tmp[]; Copy( targets, tmp // ); Clean(targets); while (HasChild(tmp)) { // int idx = -1; if (isBullish) { idx = GetLowest(tmp); } else if (isBearish) { idx = GetHighest(tmp); } // has = IsValidIndex(idx); if (!has) { break; } // XTarget iTarget = tmp[idx]; ArrayRemove( tmp, idx, 1 // ); AddRef( iTarget, targets // ); } // Clean(tmp); } // // Model an Open Position ... struct XPosition { // // Props ... // // Magic Number ... ulong magic; // // Ticket ID ... ulong ticket; // // Tradinng Symbol ... string symbol; // // Trading Period ... ENUM_TIMEFRAMES period; // // Position Type ... ENUM_POSITION_TYPE type; // // Take Profit ... double tp; // // Stop Loss ... double sl; // // Position Current Profit ... double profit; // // Position Open Price ... double entry; // // Current Symbol Price ... double price; // // Position Swap ... double swap; // // Position Commission ... double commission; // // Volume ... double volume; // // Position Open Time ... datetime openAt; // // Sifnal Provider ... string provider; // // Position Comment ... string comment; // // Constructor ... XPosition() { Clean(); } // // Initializers ... bool ByIndex(int index) { // bool result = false; // static CPositionInfo mPositionInfo; // result = mPositionInfo.SelectByIndex(index); if (!result) { return result; } // ulong mTicket = mPositionInfo.Ticket(); // result = ByTicket(mTicket); // return result; } bool ByTicket(ulong mTicket) { // bool result = false; // static CPositionInfo mPositionInfo; // result = mPositionInfo.SelectByTicket(mTicket); if (!result) { return result; } // swap = mPositionInfo.Swap(); magic = mPositionInfo.Magic(); openAt = mPositionInfo.Time(); sl = mPositionInfo.StopLoss(); ticket = mPositionInfo.Ticket(); symbol = mPositionInfo.Symbol(); tp = mPositionInfo.TakeProfit(); profit = mPositionInfo.Profit(); volume = mPositionInfo.Volume(); comment = mPositionInfo.Comment(); entry = mPositionInfo.PriceOpen(); type = mPositionInfo.PositionType(); price = mPositionInfo.PriceCurrent(); commission = mPositionInfo.Commission(); // period = ExtractPeriod(comment); provider = ExtractProvider(comment); // return result; } // // Tools ... // // Cleanup ... void Clean() { magic = 0; ticket = 0; tp = 0; sl = 0; swap = 0; entry = 0; price = 0; profit = 0; volume = 0; openAt = 0; commission = 0; // type = NULL; period = NULL; // symbol = NULL; comment = NULL; provider = NULL; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(symbol) && NotEmpty(ticket) // ; // return result; } // bool IsLong() { return IsValid() && IsXBullish(type); } // bool IsBullish() { return IsLong(); } // bool IsShort() { return IsValid() && IsXBearish(type); } // bool IsBearish() { return IsShort(); } // ENUM_X_DIRECTION GetDirection() { // return IsBullish() ? X_DIRECTION_BULLISH : IsBearish() ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Retrieve Entry Price ... double GetEntry() { // double result = 0; // if (!IsValid()) { return result; } // result = GetXEntry( symbol, type // ); // return result; } // // Retrieve Exit ... double GetExit() { // double result = 0; // if (!IsValid()) { return result; } // result = GetXExit( symbol, type // ); // return result; } // // Get Spread by Point ... double GetSpread() { // double result = 0; // if (!IsValid()) { return result; } // result = PriceToPoint(GetXSpread(symbol)); // return result; } // double GetPointsValue() { // double result = 0; // if (!IsValid()) { return result; } // result = GetPoints(symbol); // return result; } // double GetProfitInPoint() { // double result = 0; // if (!IsValid()) { return result; } // double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); // Tick size double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); // Tick value double pointSize = SymbolInfoDouble(symbol, SYMBOL_POINT); // Point size double pointValue = tickValue * pointSize / tickSize; // Point value // result = profit / (volume * tickValue); // return result; } // // Find Risk ... double GetRisk() { // double result = 0; // if (!IsValid()) { return 0; } // result = MathAbs(entry - sl); // return result; } // double GetRiskInPoint() { // double result = 0; // result = GetRisk() / GetPoints(); // return result; } // // Find Reward ... double GetReward() { // double result = 0; // if (!IsValid()) { return result; } // result = MathAbs(tp - entry); // return result; } // double GetRewardInPoint() { // double result = 0; // result = GetReward() / GetPoints(); // return result; } // // Find Risk Reward Ratio ... double GetRiskRewardRatio() { // double result = 0; // if (!IsValid()) { return result; } // result = GetReward() / GetRisk(); // return result; } // // Calculate TP Levels ... int CalculateTPLevels(double &tps[]) { // int result = 0; // SpecifiedClean(tps); // bool isValid = IsValid(); if (!isValid) { return result; } // double risk = GetRisk(); int r2r = (int)GetRiskRewardRatio(); bool isLong = IsLong(); for (int i = 0; i < r2r; i++) { // double iValue = isLong ? entry + risk + (i * risk) : entry - risk - (i * risk); // Add( iValue, tps // ); } // result = ArraySize(tps); // return result; } // // Calculate Reached TP Levels ... void CalculateReahedTP( double &reachedLevel, double &reachedPrice // ) { // reachedLevel = -1; reachedPrice = 0; double tps[]; bool isLong = IsLong(); double exitPrice = GetExit(); int tpLevels = CalculateTPLevels(tps); if (!IsValidSize(tpLevels) || exitPrice <= 0) { return; } // for (int i = 0; i < tpLevels - 1; i++) { // double cTP = tps[i]; double nTP = tps[i + 1]; // bool isReached = isLong ? exitPrice > cTP && exitPrice < nTP : exitPrice < cTP && exitPrice > nTP; if (isReached) { // reachedLevel = i + 1; reachedPrice = cTP; } } } // // Calculate Touched Reward ... double CalculateTouchedReward() { // double result = 0.0; // bool has = IsValid() && profit > 0; if (!has) { return result; } // double risk = MathAbs(entry - sl); double currentReward = MathAbs(price - entry); // result = currentReward / risk; // return result; } // // Calculate Age ... int GetAge( ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period ) { return GetXAge(this, mPeriod); } // // Check this instance is Same os Given instance or not ... bool IsSameAs( const XPosition &value // instance for Compare ) { // bool result = false; // result = // type == value.type && magic == value.magic && entry == value.entry && ticket == value.ticket && volume == value.volume && symbol == value.symbol && provider == value.provider // ; // return result; } // // Find index in a Collection ... int FindIndex( XPosition &values[] // Collection to Find ) { // return FindXIndex( this, values // ); } // // Check Items Passed Specific Filters or not ... bool IsFiltersPassed( string mSymbol = NULL, // Trading Symbol string mProvider = NULL, // Signal Provider ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe ENUM_X_POSITION_TYPES mType = NULL, // Long (Buy), Short (Sell) ulong mMagic = NULL, // Magic Number bool mFilterByMagic = true // Get Only Self Open Positions ) { // bool result = false; // result = // // Magic Filter ... IsMagicFilterPassed( mMagic, mFilterByMagic, this // ) // && // // Symbol Filter ... IsSymbolFilterPassed( mSymbol, this // ) // && // // Provider Filter ... IsProviderFilterPassed( mProvider, this // ) // && // // Period Filter ... IsPeriodFilterPassed( mPeriod, this // ) // && // // Type Filter ... IsTypeFilterPassed( mType, this // ) // ; // return result; } }; // // Model a Signal ... struct XSignal { // // Props ... // ulong positionId; // if Executed this filled ... // datetime time; // Issue Time ... // double tp; // Take Profit ... double sl; // Stop Loss ... double entry; // Exntry or Execution Price ... double volume; // Position Volume ... // string symbol; // Trading Symbol ... string comment; // Comment ... string provider; // Signaller ... // ENUM_TIMEFRAMES period; // Trading TimeFrame ... ENUM_POSITION_TYPE type; // Long (Buy) or Short (Sell) ... ENUM_X_ORDER_MODES mode; // Execution Mode ... // string conditions; // Signal Conditions ... // // Additional ... // // Traget ... XTarget targets[]; // Provided Targets ... int appliedTargetIDX; // Last Applied Target Index ... bool ignoreEAVolume; // Ignore EA Volume ... bool isTargetApplied; // Check if Target Applied or not ... // // Constructor ... XSignal() { Default(); } // // Tools ... // // Cleanup ... void Clean() { // entry = 0; volume = 0; positionId = 0; // time = NULL; type = NULL; mode = NULL; symbol = NULL; period = NULL; comment = NULL; provider = NULL; conditions = NULL; // SpecifiedClean(targets); appliedTargetIDX = -1; ignoreEAVolume = false; isTargetApplied = false; // ZeroMemory(this); } // // Default Values ... void Default() { // entry = 0; volume = 0; positionId = 0; // time = NULL; type = NULL; mode = NULL; symbol = NULL; period = NULL; comment = NULL; provider = NULL; conditions = NULL; // SpecifiedClean(targets); appliedTargetIDX = -1; ignoreEAVolume = false; isTargetApplied = false; } // // Validate ... bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(period) && IsSpecifiedValid(symbol) && NotEmpty(volume) && NotEmpty(entry) // ; // if (!result) { return result; } // return result; } // // DO All Calculations and Normalizations ... bool Normalize() { // bool result = false; // // Normalizations ... symbol = NormalizeSymbol(symbol); period = NormalizePeriod(period); // time = NormalizeTime(time); // sl = NormalizePrice(sl, symbol); tp = NormalizePrice(tp, symbol); entry = NormalizePrice(entry, symbol); volume = NormalizeVolume(volume, symbol); // result = IsValid(); // return result; } // // Check Signal Executed or not ... bool IsExecuted() { // bool result = false; // result = // IsValid() && NotEmpty(positionId) // ; // return result; } // // Generate Comment for Signal ... string GenerateComment() { // string result = NULL; // if (!IsValid()) { return result; } // if (IsSpecifiedValid(provider)) { // // Generate Provider Tag ... result += GenerateProviderTag(provider); } // if (IsSpecifiedValid(period)) { // // Generate Period Tag ... result += GeneratePeriodTag(period); } // return result; } // int GetAge() { // return GetXAge( this, this.period // ); } // // Find Risk ... double GetRisk() { // double result = 0; // if (!IsValid()) { return 0; } // result = MathAbs(entry - sl); // return result; } // // Find Reward ... double GetReward() { // double result = 0; // if (!IsValid()) { return result; } // result = MathAbs(tp - entry); // return result; } // // Find Risk Reward Ratio ... double GetRiskRewardRatio() { // double result = 0; // if (!IsValid()) { return result; } // result = GetReward() / GetRisk(); // return result; } // string GetTag() { // string result = NULL; // result = "XSignal_" + symbol + "_" + ToXString(period) + "_" + ToXString(type) + "_" + ToXString(sl) + "_" + ToXString(tp) + "_" + ToXString(entry); // return result; } // string GetObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = "XSignal_" + symbol + "_" + ToXString(period) + "_" + ToXString(type) + "_" + ToXString(TimeToSeconds(time)); // return result; } // // Retrieve String Representation of Signal ... string ToString() { // string result = NULL; // result = // ToXString("Symbol", symbol) + ToXString("Period", period) + ToXString("Provider", provider) + ToXString("Type", type) + ToXString("Mode", mode) + ToXString("Volume", volume) + ToXString("Entry", entry) + ToXString("TP", tp) + ToXString("SL", sl) + ToXString("Time", time) + ToXString("Comment", comment) + // "" // ; // return result; } // bool IsSameAs(XSignal &item) { // bool result = false; // result = // IsValid() && item.IsValid() && // tp == item.tp && sl == item.sl && mode == item.mode && time == item.time && type == item.type && entry == item.entry && symbol == item.symbol && period == item.period && provider == item.provider // ; // return result; } // string GetMessage(string action = NULL) { // string result = NULL; // if (!IsValid()) { return result; } // result = ToXString(type) + " Signal" + (!IsSpecifiedValid(action) ? "" : " " + action) + " by: " + provider + " on (" + symbol + ")" + " in: " + ToXString(period); // return result; } // string GetFileName() { // string result = NULL; // if (!IsValid()) { return result; } // result = // symbol + "\\" + ToXString(type) + "\\" + ToXString(period) + "_" + ToFormatString(time) // ; // return result; } }; // // Model an Order ... struct XOrder { // // Time of order placement ... datetime setupAt; // // Time of order expiration ... datetime expiredAt; // // Time of order execution or cancellation ... datetime executedAt; // // Order type ... ENUM_ORDER_TYPE type; // // Order state ... ENUM_ORDER_STATE state; // // Type of execution by remainder ... ENUM_ORDER_TYPE_FILLING filling; // // Order lifetime ... ENUM_ORDER_TYPE_TIME lifetime; // // Order ticket ... ulong ticket; // // Magic Number ... long magic; // // Position id, that is placed on order, // when it is executed. Each executed order invokes a // deal, that opens new or changes existing // position. Id of that position is placed on // executed order in this moment. long positionId; // // Initial volume on order placement ... double initialVolume; // // Unfilled volume ... double currentVolume; // // Price, specified in the order ... double openPrice; // // Current price by order symbol ... double currentPrice; // // Price of placing Limit order when StopLimit order is triggered ... double stopLimitPrice; // // Take Profit level ... double tp; // // Stop Loss level ... double sl; // // Trading Symbol ... string symbol; // // Signal Provider ... string provider; // // Order Comment ... string comment; // ENUM_TIMEFRAMES period; // // Constructor ... XOrder() { Clean(); } // // Initializers ... bool ByIndex( int index // Fill By Index ... ) { // bool result = false; // int ordersCount = OrdersTotal(); if (ordersCount <= 0) { return result; } // static COrderInfo mOrderInfo; // result = mOrderInfo.SelectByIndex(index); if (!result) { return result; } // // Reading Order Info ... magic = mOrderInfo.Magic(); sl = mOrderInfo.StopLoss(); tp = mOrderInfo.TakeProfit(); ticket = mOrderInfo.Ticket(); openPrice = mOrderInfo.PriceOpen(); positionId = mOrderInfo.PositionId(); currentPrice = mOrderInfo.PriceCurrent(); initialVolume = mOrderInfo.VolumeInitial(); currentVolume = mOrderInfo.VolumeCurrent(); stopLimitPrice = mOrderInfo.PriceStopLimit(); // symbol = mOrderInfo.Symbol(); comment = mOrderInfo.Comment(); // state = mOrderInfo.State(); type = mOrderInfo.OrderType(); lifetime = mOrderInfo.TypeTime(); filling = mOrderInfo.TypeFilling(); // setupAt = mOrderInfo.TimeSetup(); executedAt = mOrderInfo.TimeDone(); expiredAt = mOrderInfo.TimeExpiration(); // period = ExtractPeriod(comment); provider = ExtractProvider(comment); // result = IsValid(); // return result; } // // Retrieve Specific History Order ... bool HistoryByIndex( int index // Fill By Index ... ) { // bool result = false; // int ordersCount = HistoryOrdersTotal(); if (ordersCount <= 0) { return result; } // static CHistoryOrderInfo mOrderInfo; // result = mOrderInfo.SelectByIndex(index); if (!result) { return result; } // // Reading Order Info ... magic = mOrderInfo.Magic(); sl = mOrderInfo.StopLoss(); tp = mOrderInfo.TakeProfit(); ticket = mOrderInfo.Ticket(); openPrice = mOrderInfo.PriceOpen(); positionId = mOrderInfo.PositionId(); currentPrice = mOrderInfo.PriceCurrent(); initialVolume = mOrderInfo.VolumeInitial(); currentVolume = mOrderInfo.VolumeCurrent(); stopLimitPrice = mOrderInfo.PriceStopLimit(); // symbol = mOrderInfo.Symbol(); comment = mOrderInfo.Comment(); // state = mOrderInfo.State(); type = mOrderInfo.OrderType(); lifetime = mOrderInfo.TypeTime(); filling = mOrderInfo.TypeFilling(); // setupAt = mOrderInfo.TimeSetup(); executedAt = mOrderInfo.TimeDone(); expiredAt = mOrderInfo.TimeExpiration(); // period = ExtractPeriod(comment); provider = ExtractProvider(comment); // result = IsValid(); // return result; } // // Tools ... // // Cleanup ... void Clean() { // tp = 0; sl = 0; magic = 0; ticket = 0; positionId = 0; openPrice = 0; currentPrice = 0; initialVolume = 0; currentVolume = 0; stopLimitPrice = 0; // setupAt = NULL; expiredAt = NULL; executedAt = NULL; // symbol = NULL; comment = NULL; provider = NULL; // type = NULL; state = NULL; period = NULL; filling = NULL; lifetime = NULL; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(symbol) && NotEmpty(ticket) && NotEmpty(positionId) // ; // return result; } // // Calculate Age ... int GetAge( ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period ) { return GetXAge(this, mPeriod); } // // Check this instance is Same os Given instance or not ... bool IsSameAs( const XOrder &value // instance for Compare ) { // bool result = false; // result = // type == value.type && state == value.state && magic == value.magic && ticket == value.ticket && symbol == value.symbol && provider == value.provider && positionId == value.positionId // ; // return result; } // // Find index in a Collection ... int FindIndex( XOrder &values[] // Collection to Find ) { // return FindXIndex( this, values // ); } // // Check Items Passed Specific Filters or not ... bool IsFiltersPassed( string mSymbol = NULL, // Trading Symbol string mProvider = NULL, // Signal Provider ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe ENUM_X_POSITION_TYPES mType = NULL, // Long (Buy), Short (Sell) ENUM_ORDER_STATE mState = NULL, // Order State ulong mMagic = NULL, // Magic Number bool mFilterByMagic = true // Get Only Self Open Positions ) { // bool result = false; // result = // // Magic Filter ... IsMagicFilterPassed( mMagic, mFilterByMagic, this // ) // && // // Symbol Filter ... IsSymbolFilterPassed( mSymbol, this // ) // && // // Provider Filter ... IsProviderFilterPassed( mProvider, this // ) // && // // Period Filter ... IsPeriodFilterPassed( mPeriod, this // ) // && // // Type Filter ... IsTypeFilterPassed( mType, this // ) // && // // State Filter ... IsStateFilterPassed( mState, this // ) // ; // return result; } }; // // Model a Deal ... struct XDeal { // // the ID of the Expert Advisor, that executed the deal ... ulong magic; // // the ID of position, in which the deal was involved ... ulong positionId; // // Ticket ... ulong ticket; // // the name of the deal symbol ... string symbol; // // order by which the deal is executed ... ulong order; // // the time of deal execution ... datetime time; // // Deal price ... double price; // // the financial result of the deal (in deposit currency) ... double profit; // // the amount of swap when position is closed ... double swap; // // the amount of commission of the deal ... double commission; // // the volume of deal ... double volume; // // the deal comment ... string comment; // string provider; // ENUM_TIMEFRAMES period; // // the deal type ... // ------------------------------------------------------------------ // DEAL_TYPE_BUY => Buy ... // DEAL_TYPE_SELL => Sell ... // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... // There can be a situation when a previously executed buy deal is canceled. In this case, // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... // // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... // There can be a situation when a previously executed sell deal is canceled. In this case, // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation // // DEAL_TYPE_BALANCE => Balance ... // DEAL_TYPE_CREDIT => Credit ... // DEAL_TYPE_CHARGE => Additional charge ... // DEAL_TYPE_CORRECTION => Correction ... // DEAL_TAX => Tax charges ... // DEAL_TYPE_BONUS => Bonus ... // DEAL_TYPE_INTEREST => Interest rate ... // DEAL_DIVIDEND => Dividend operations... // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... // DEAL_TYPE_COMMISSION => Additional commission ... // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission ENUM_DEAL_TYPE type; // // the deal direction ... // ---------------------------------- // DEAL_ENTRY_IN => Entry in ... // DEAL_ENTRY_OUT => Entry out ... // DEAL_ENTRY_INOUT => Reverse ... // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... ENUM_DEAL_ENTRY entry; // // deal reson ... // --------------------- // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... ENUM_DEAL_REASON reason; // // Constructor ... XDeal() { Clean(); } // // Initializers ... bool ByIndex( int index // Deal Index ) { // bool result = false; // int dealsCount = HistoryDealsTotal(); result = dealsCount > 0; if (!result) { return result; } // static CDealInfo mDealInfo; // result = mDealInfo.SelectByIndex(index); if (!result) { // return result; } // // Reading Order Info ... swap = mDealInfo.Swap(); magic = mDealInfo.Magic(); order = mDealInfo.Order(); ticket = mDealInfo.Ticket(); time = mDealInfo.Time(); price = mDealInfo.Price(); symbol = mDealInfo.Symbol(); profit = mDealInfo.Profit(); volume = mDealInfo.Volume(); comment = mDealInfo.Comment(); positionId = mDealInfo.PositionId(); entry = mDealInfo.Entry(); commission = mDealInfo.Commission(); type = mDealInfo.DealType(); reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( ticket, DEAL_REASON); // period = ExtractPeriod(comment); provider = ExtractProvider(comment); // result = IsValid(); // return result; } // // Tools ... // // Cleanup ... void Clean() { // magic = 0; positionId = 0; ticket = 0; order = 0; time = 0; price = 0; profit = 0; swap = 0; commission = 0; volume = 0; // symbol = NULL; comment = NULL; provider = NULL; // type = NULL; entry = NULL; period = NULL; reason = NULL; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = // IsSpecifiedValid(symbol) && NotEmpty(ticket) && NotEmpty(positionId) // ; // return result; } // // Calculate Age ... int GetAge( ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period ) { return GetXAge(this, mPeriod); } // // Check this instance is Same os Given instance or not ... bool IsSameAs( const XDeal &value // instance for Compare ) { // bool result = false; // result = // type == value.type && magic == value.magic && entry == value.entry && reason == value.reason && ticket == value.ticket && volume == value.volume && symbol == value.symbol && provider == value.provider && positionId == value.positionId // ; // return result; } // // Find index in a Collection ... int FindIndex( XDeal &values[] // Collection to Find ) { // return FindXIndex( this, values // ); } // // Check Items Passed Specific Filters or not ... bool IsFiltersPassed( string mSymbol = NULL, // Trading Symbol string mProvider = NULL, // Signal Provider ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe ENUM_DEAL_TYPE mType = NULL, // Deal Type ENUM_DEAL_ENTRY mEntry = NULL, // Deal Entry ENUM_DEAL_REASON mReason = NULL, // Deal Reason ulong mMagic = NULL, // Magic Number bool mFilterByMagic = true // Get Only Self Open Positions ) { // bool result = false; // result = // // Magic Filter ... IsMagicFilterPassed( mMagic, mFilterByMagic, this // ) // && // // Symbol Filter ... IsSymbolFilterPassed( mSymbol, this // ) // && // // Provider Filter ... IsProviderFilterPassed( mProvider, this // ) // && // // Period Filter ... IsPeriodFilterPassed( mPeriod, this // ) // && // // Type Filter ... IsTypeFilterPassed( mType, this // ) // && // // Entry Filter ... IsEntryFilterPassed( mEntry, this // ) // && // // Reason Filter ... IsReasonFilterPassed( mReason, this // ) // ; // return result; } }; // // Model OnTrade Event Handler Result on XCTrade Class ... struct XOnTradeHandlerState { // bool hasNewDeal; int newDeals; // bool hasNewOrder; int newOrders; // bool hasNewPosition; int newPositions; // bool hasNewHistoryOrder; int newHistoryOrders; // // Constructor ... XOnTradeHandlerState() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // hasNewDeal = false; hasNewOrder = false; hasNewPosition = false; hasNewHistoryOrder = false; // newDeals = 0; newOrders = 0; newPositions = 0; newHistoryOrders = 0; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = // ( // hasNewDeal ? newDeals > 0 : true // ) // && // ( // hasNewOrder ? newOrders > 0 : true // ) // && // ( // hasNewPosition ? newPositions > 0 : true // ) // && // ( // hasNewHistoryOrder ? newHistoryOrders > 0 : true // ) // ; // return result; } }; // // an Structure for Describe aTrading Session ... struct XTradeSession { // // Properties ... string start; // Session Start Time (hh:mm) string end; // Session End Time (hh:mm) string name; // Session Name // // Constructor ... XTradeSession() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // end = NULL; name = NULL; start = NULL; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = IsSpecifiedValid(start) && IsSpecifiedValid(end); if (!result) { return result; } // return result; } // // Check Session is Active or Not ... bool IsActive(datetime time = NULL) { // bool result = false; // time = NormalizeTime(time); // result = IsValid(); if (!result) { return result; } // result = IsTimeInRange( time, start, end // ); // return result; } }; // // an Structure for Describe an Specified Symbols // Trading Sessions ... struct XSymbolTradeConfig { // // Propeties ... // int longs; // All Long Trades int shorts; // All Short Trades int trades; // All Trades int losses; // All Loosing Trades int profits; // All Winning Trades string name; // Provider Name string symbol; // Trading Symbol int managedSLs; // Managed SL(s) int managedTPs; // Managed TP(s) int managedTrades; // Managed Trades int maxAllowedTPs; // Max Allowed TP(s) in Restrictions Period int maxAllowedSLs; // Max Allowed SL(s) in Restrictions Period int maxAllowedTrades; // Max Allowed Trades in Restrictions Period datetime managedStart; // Managed Start Time double managedBalance; // Managed Start Balance double managedProfits; // Managed Profit(s) ENUM_TIMEFRAMES period; // Trading Period int maxAllowedPositions; // Max Allowed Same Time Trades double maxAllowedSpread; // Max Allowed Spread For Trade bool isForceCloseAtTime; // a Flag for Determines Force Closed or not XTradeSession sessions[]; // Trading Sessions string closeAllOpenTradesAt; // Close All Open Trades per Day At Specified Time int restrictionsPeriodMultiplier; // Specified Restrictions Period Multiplier ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod; // Trade Restrictions Period // // Constructor ... XSymbolTradeConfig() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // name = NULL; symbol = NULL; period = NULL; SpecifiedClean(sessions); // longs = 0; shorts = 0; trades = 0; losses = 0; profits = 0; // managedStart = NULL; // managedSLs = 0; managedTPs = 0; managedTrades = 0; // managedBalance = 0; managedProfits = 0; // maxAllowedTPs = 0; maxAllowedSLs = 0; maxAllowedTrades = 0; maxAllowedSpread = 25; maxAllowedPositions = 5; closeAllOpenTradesAt = ""; isForceCloseAtTime = false; restrictionsPeriod = XTRADE_RESTRICATION_NONE; // ZeroMemory(this); } /** * Initial ... * * @param _symbol: Trading Symbol * @param _period: Trading Period * @param _sessionsDescriptor: Sessions Description * @param _maxAllowedSpread: Max Allowed Spread for Open Trade * @param _maxAllowedPositions: Max Allowed Same Time Position * @param _restrictionsDescriptor: Restrictions Descriptor * * @return ( bool ) */ bool Init( string _name, string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL, string _sessionsDescriptor = NULL, double _maxAllowedSpread = 25, int _maxAllowedPositions = 5, string _restrictionsDescriptor = NULL // ) { // bool result = false; // // Normalize Symbol ... _symbol = NormalizeSymbol(_symbol); _period = NormalizePeriod(_period); // name = _name; symbol = _symbol; period = _period; maxAllowedSpread = _maxAllowedSpread; maxAllowedPositions = _maxAllowedPositions; // // Parse Sessions ... ParseSessions(_sessionsDescriptor); // // Parse Restrictions ... ParseRestrictions(_restrictionsDescriptor); // // Check Validation ... result = IsValid(); // return result; } // // Check Same ... bool IsSame(XSymbolTradeConfig &dest) { // bool result = false; // // Validate ... result = IsValid() && dest.IsValid() && name == dest.name && symbol == dest.symbol && period == dest.period; // return result; } // // Validate ... bool IsValid() { // bool result = false; // result = IsSpecifiedValid(name) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period); // return result; } // // Check Allow Trade in Active Sessions ... bool CanTrade(datetime time = NULL) { // bool result = false; // // Normalize Args ... time = NormalizeTime(time); // // Validating ... result = IsValid(); if (!result) { return result; } // // if there is not any defined sessions for Symbol ... // it's allow Trading in all times ... result = !HasChild(sessions); if (result) { return result; } // // Detect an Active Session ... int count = ArraySize(sessions); for (int i = 0; i < count; i++) { // result = sessions[i].IsActive(time); if (result) { break; } } // return result; } // // Checking Restrictions ... bool IsRestricted(datetime time = NULL) { // bool result = false; // // Normalize Time ... time = NormalizeTime(time); // // Check Has Restrictions ... bool has = HasRestrictions(restrictionsPeriod); result = !has; if (result) { return result; } // // Check Restrictions Time ... has = IsSpecifiedValid(managedStart) && time <= managedStart; result = !has; if (result) { return result; } // // Validate Restrictions Timing ... // Check Restrictions ... // bool isTPAllowed = maxAllowedTPs == 0 ? true : managedTPs < maxAllowedTPs; bool isSLAllowed = maxAllowedSLs == 0 ? true : managedSLs < maxAllowedSLs; bool isTradeAllowed = maxAllowedTrades == 0 ? true : managedTrades < maxAllowedTrades; // result = isTPAllowed && isSLAllowed && isTradeAllowed; if (result) { return result; } // // Check Restrictions Reset ... HandleRestrictions(); // return result; } // // Parse Sessions ... void ParseSessions(string descriptor) { // // Validate ... if (!IsSpecifiedValid(descriptor)) { return; } // bool has = false; string _sessions[]; int sessionsCount = 0; // // Extract Per Symbol Sessions ... sessionsCount = SplitContent( _sessions, descriptor, "," // ); // // Try to Extract Start and End Times Series ... has = IsValidSize(sessionsCount); if (!has) { return; } // // Iterate Sessions ... for (int i = 0; i < sessionsCount; i++) { // // Ignore unused Cases and Extracts only Content ... string iSessionDescriptorStr = ExtractString(_sessions[i]); has = IsSpecifiedValid(iSessionDescriptorStr); if (has) { // // Extract Session Descriptor Data ... string parts[]; int partsCount = SplitContent( parts, iSessionDescriptorStr, "_" // ); has = IsValidSize(partsCount) && partsCount == 3; if (has) { // string iName = parts[0]; string iStart = parts[1]; string iEnd = parts[2]; has = IsSpecifiedValid(iName) && IsSpecifiedValid(iStart) && IsSpecifiedValid(iEnd); if (has) { // // Set Active Session Per Symbols ... XTradeSession session; // session.end = iEnd; session.name = iName; session.start = iStart; // AddRef( session, sessions // ); // session.Clean(); } } // SpecifiedClean(parts); } } // SpecifiedClean(_sessions); } // // Parse Restrictions ... void ParseRestrictions(string descriptor) { // // Validate ... if (!IsSpecifiedValid(descriptor)) { return; } // // Extract Content ... descriptor = ExtractString(descriptor); if (!IsSpecifiedValid(descriptor)) { return; } // int count = 0; bool has = false; string iRestrictionsParts[]; // // Extract Parts ... count = SplitContent( iRestrictionsParts, descriptor, "," // ); has = IsValidSize(count); if (!has) { // // Default Restrictions ... ApplyDefaultRestrictions(); return; } // // Try To Extract Required Parts ... bool hasRestrictionsPeriod = count >= 1; bool hasRestrictionsPeriodMultiplier = count >= 2; bool hasMaxAllowedTPs = count >= 3; bool hasMaxAllowedSLs = count >= 4; bool hasMaxAllowedTrades = count >= 5; bool hasCloseAllOpenTradesAt = count >= 6; // // Restrictions Period ... restrictionsPeriod = hasRestrictionsPeriod ? ToXRestrictionPeriod(Trim(iRestrictionsParts[0])) : XTRADE_RESTRICATION_NONE; // // Restrictions Period Multiplier ... restrictionsPeriodMultiplier = hasRestrictionsPeriodMultiplier ? (int)(Trim(iRestrictionsParts[1])) : 1; // // Max Allowed TPs ... maxAllowedTPs = hasMaxAllowedTPs ? (int)(Trim(iRestrictionsParts[2])) : 0; // // Max Allowed SLs ... maxAllowedSLs = hasMaxAllowedSLs ? (int)(Trim(iRestrictionsParts[3])) : 0; // // Max Allowed Trades ... maxAllowedTrades = hasMaxAllowedTrades ? (int)(Trim(iRestrictionsParts[4])) : 0; // // Close All Open Trades At ... closeAllOpenTradesAt = hasCloseAllOpenTradesAt ? Trim(iRestrictionsParts[5]) : NULL; } // // Apply Default Restrictions ... void ApplyDefaultRestrictions() { // maxAllowedTPs = 0; maxAllowedSLs = 0; maxAllowedTrades = 0; closeAllOpenTradesAt = NULL; restrictionsPeriod = XTRADE_RESTRICATION_NONE; } // // Handle Restrictions ... void HandleRestrictions(datetime time = NULL) { // // Normalize Time ... time = NormalizeTime(time); // // Check Restrictions Requirements ... bool has = HasRestrictions(restrictionsPeriod) && restrictionsPeriodMultiplier >= 1; if (!has) { return; } // // Check Restrictions Start ... has = IsSpecifiedValid(managedStart); if (!has) { managedStart = time; } // // Calculating Expiration Date based on Config ... int expiredDelay = restrictionsPeriodMultiplier * GetXRestrictionsPeriodSeconds(restrictionsPeriod); datetime expiredDate = (datetime)(TimeToSeconds(managedStart) + expiredDelay); // // Check Expiration ... has = time >= expiredDate; if (!has) { return; } // ResetRestrictions(); } // // Reset Restrictions ... void ResetRestrictions() { // managedSLs = 0; managedTPs = 0; managedTrades = 0; managedBalance = 0; managedProfits = 0; managedStart = TimeCurrent(); } // }; // // an Structure to Describe a Trade ... struct XTradeInfo { // // Props ... double swap; double profit; XSignal signal; ulong positionID; double commission; string conditions; double bullishScore; double bearishScore; ENUM_XTRADE_FINALIZATION finalize; // datetime signaledAt; datetime executedAt; datetime finalizedAt; // // Constructor ... XTradeInfo() { Clean(); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // swap = 0; profit = 0; signal.Clean(); commission = 0; positionID = 0; conditions = NULL; bullishScore = 0; bearishScore = 0; finalize = XTRADE_FINAL_NONE; // signaledAt = NULL; executedAt = NULL; finalizedAt = NULL; // ZeroMemory(this); } /** * Check Has Signal ... * * @return ( bool ) */ bool HasSignal() { // bool result = false; // result = signal.IsValid(); // return result; } /** * Check Signal Executed or Not ... * * @return ( bool ) */ bool IsExecuted() { // bool result = false; // result = positionID > 0; // return result; } /** * Check a Trade is Finalized or not ... * * @return ( bool ) */ bool IsFinalized() { // bool result = false; // result = HasSignal() && IsExecuted() && finalize != XTRADE_FINAL_NONE; // return result; } /** * Generate Summary Info ... * * @return ( string ) */ string Summary() { // string result = NULL; // result = // ToXString("Swap", swap) + ToXString("Profit", profit) + ToXString("Commission", commission) + ToXString("Finalize", ToXString(finalize)) + ToXString("PositionID", positionID) + ToXString("----------------") + "\n" + ToXString("Signaled At", ToFormatString(signaledAt)) + ToXString("Executed At", ToFormatString(executedAt)) + ToXString("Finalized At", ToFormatString(finalizedAt)) // ; // return result; } /** * Get Data Collection File Name ... * * @return ( string ) */ string GetFileName() { // string result = NULL; // bool hasSignal = HasSignal(); bool isExecuted = IsExecuted(); bool isFinalized = IsFinalized(); if (!hasSignal && !isExecuted && !isFinalized) { return result; } // result = // signal.symbol + "\\" + ToString(signal.type) + "\\" + (profit >= 0 ? "Profit" : "Loss") + "\\" + ToString(positionID) + "_" + ToString(signal.period) + "_" + ToFormatString(signaledAt) // ; // return result; } /** * Converts Model to String Representation ... * * @param onlySignals: Boolean, Specified Represent Only Signal or not ... * * @return ( string ) */ string ToString( bool includeSummary = true, bool includeSignal = true, bool includeConditions = true // ) { // string result = NULL; // // Generating Model Summary ... string summary = Summary(); // // Generating Signal Summary ... string signalSummary = signal.ToString(); // if (includeSummary) { // result += ToXString("----------------") + "\n" + ToXString("Summary: ") + "\n" + ToXString("----------------") + "\n" + summary + "\n"; } // if (includeSignal) { // result += ToXString("----------------") + "\n" + ToXString("Signal: ") + "\n" + ToXString("----------------") + "\n" + signalSummary + "\n"; } // if (includeConditions) { // result += ToXString("----------------") + "\n" + ToXString("Conditions: ") + "\n" + ToXString("----------------") + "\n" + conditions + "\n"; } // return result; } string GetConditionsString() { // string result = NULL; // string conditionsStr = conditions; string condParts[]; int condPartsCount = SplitContent( condParts, conditionsStr, "\n" // ); if (IsValidSize(condPartsCount)) { // conditionsStr = NULL; while (HasChild(condParts)) { // string iStr = condParts[0]; ArrayRemove( condParts, 0, 1 // ); // bool isLast = !HasChild(condParts); // bool isCond = Contains( "is", iStr, false // ); if (isCond) { // string iParts[]; int iPartsCount = SplitContent( iParts, iStr, ":" // ); if (iPartsCount == 2) { // string iVal = iParts[1]; StringTrimLeft(iVal); StringTrimRight(iVal); bool isPassed = ToBoolean(iVal); conditionsStr += (isPassed ? "" : "!") + "conditions." + iParts[0] + (!isLast ? " &&" : "") + "\n"; } } } SpecifiedClean(condParts); } else { conditionsStr = NULL; } // result = "(" + "\n" + "\\" + "\\" + " " + ToXString("Type", ToXString(signal.type)) + "\\" + "\\" + " " + ToXString("Profit", profit) + "\\" + "\\" + " " + ToXString("Finalize", ToXString(finalize)) + "\\" + "\\" + " " + ToXString("PositionID", positionID) + "\\" + "\\" + " " + ToXString("----------------") + "\n" + "\\" + "\\" + " " + ToXString("Signaled At", ToFormatString(signaledAt)) + "\\" + "\\" + " " + ToXString("Executed At", ToFormatString(executedAt)) + "\\" + "\\" + " " + ToXString("Finalized At", ToFormatString(finalizedAt)) + "\\" + "\\" + " " + ToXString("----------------") + "\n" + "\\" + "\\" + " " + ToXString("Scores:") + "\n" + "\\" + "\\" + " " + ToXString("Bullish", bullishScore) + "\\" + "\\" + " " + ToXString("Bearish", bearishScore) + "\\" + "\\" + " " + ToXString("----------------") + "\n" + conditionsStr + (IsValid(conditionsStr) ? "" : "") + ") && "; // return result; } }; // // TypeDefs ... // typedef void (*TOnSignal)(XSignal &signal); // typedef bool (*TCanAnalyse)( string _symbol, ENUM_TIMEFRAMES _period, datetime _time // ); // // an Event Type for Notify Guard Triggered ... typedef void (*TOnGuarded)( ENUM_X_GUARD_ACTIONS guard, XPosition &positions[]); // typedef int (*TCheckForGuard)( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ); // typedef void (*TOnDealsChanged)(int count); // typedef void (*TOnOrdersChanged)(int count); // typedef void (*TOnPositionsChanged)(int count); // typedef void (*TOnStopLoss)(const XDeal &deal); typedef void (*TOnTakeProfit)(const XDeal &deal); // typedef void (*TOnTradeStateChanged)(const XOnTradeHandlerState &state); // typedef void (*TOnForceClose)( const ulong ticket, const XPosition &position, const string comment // ); // typedef void (*TOnPartialClose)( const ulong ticket, const double profit, const string comment // ); // typedef void (*TOnModify)( const ulong ticket, const double profit, const string comment // ); // // Classes ... // // Tools ... // bool IsValid(ENUM_X_ORDER_MODES value) { return value != X_ORDER_MODE_NOTHING; } // bool IsXBullish(ENUM_POSITION_TYPE type) { return type == POSITION_TYPE_BUY; } // bool IsXBullish(ENUM_X_POSITION_TYPES type) { return type == X_POSITION_TYPE_LONG; } // bool IsXBearish(ENUM_POSITION_TYPE type) { return type == POSITION_TYPE_SELL; } // bool IsXBearish(ENUM_X_POSITION_TYPES type) { return type == X_POSITION_TYPE_SHORT; } // // Ages ... // // Retrieve a Position Age ... int GetAge( XSignal &signal, // Selected Signal ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { // int result = -1; // if (period == NULL) { period = _Period; } // result = iBarShift( signal.symbol, period, signal.time); // return result; } int GetXAge( XSignal &signal, // Selected Signal ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { return GetAge(signal, period); } // // Retrieve a Position Age ... int GetAge( XPosition &position, // Selected Position ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { // int result = -1; // if (period == NULL) { period = _Period; } // result = iBarShift( position.symbol, period, position.openAt); // return result; } int GetXAge( XPosition &position, // Selected Position ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { return GetAge(position, period); } // // Retrieve an Order Age ... int GetAge( XOrder &order, // Selected Order ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { // int result = -1; // if (period == NULL) { period = _Period; } // result = iBarShift( order.symbol, period, order.setupAt); // return result; } int GetXAge( XOrder &order, // Selected Order ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { return GetAge(order, period); } // // Retrieve a Deal Age ... int GetAge( XDeal &deal, // Selected Deal ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { // int result = -1; // if (period == NULL) { period = _Period; } // result = iBarShift( deal.symbol, period, deal.time); // return result; } int GetXAge( XDeal &deal, // Selected Deal ... ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... ) { return GetAge(deal, period); } // // Get Oldest Deal ... int GetOldest( XDeal &item, // Hold Result ... XDeal &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XDeal tmpItem; for (int i = 0; i < itemsCount; i++) { // XDeal iItem = items[i]; // int iAge = GetAge(iItem); if (iAge > 0 && (tmpAge == 0 || tmpAge < iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge > 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXOldest( XDeal &item, // Hold Result ... XDeal &items[] // Source Array ... ) { return GetOldest(item, items); } // // Get Youngest Deal ... int GetYoungest( XDeal &item, // Hold Result ... XDeal &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XDeal tmpItem; for (int i = 0; i < itemsCount; i++) { // XDeal iItem = items[i]; // int iAge = GetAge(iItem); if (iAge > 0 && (tmpAge == 0 || tmpAge > iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge > 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXYoungest( XDeal &item, // Hold Result ... XDeal &items[] // Source Array ... ) { return GetYoungest(item, items); } // // Get Oldest Order ... int GetOldest( XOrder &item, // Hold Result ... XOrder &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XOrder tmpItem; for (int i = 0; i < itemsCount; i++) { // XOrder iItem = items[i]; // int iAge = GetAge(iItem); if (iAge > 0 && (tmpAge == 0 || tmpAge < iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge > 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXOldest( XOrder &item, // Hold Result ... XOrder &items[] // Source Array ... ) { return GetOldest(item, items); } // // Get Youngest Order ... int GetYoungest( XOrder &item, // Hold Result ... XOrder &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XOrder tmpItem; for (int i = 0; i < itemsCount; i++) { // XOrder iItem = items[i]; // int iAge = GetAge(iItem); if (iAge > 0 && (tmpAge == 0 || tmpAge > iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge > 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXYoungest( XOrder &item, // Hold Result ... XOrder &items[] // Source Array ... ) { return GetYoungest(item, items); } // // Get Oldes Position ... int GetOldest( XPosition &item, // Hold Result ... XPosition &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XPosition tmpItem; for (int i = 0; i < itemsCount; i++) { // XPosition iItem = items[i]; // int iAge = GetAge(iItem); if (iAge > 0 && (tmpAge == 0 || tmpAge < iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge > 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXOldest( XPosition &item, // Hold Result ... XPosition &items[] // Source Array ... ) { return GetOldest(item, items); } // // Get Youngest Position ... int GetYoungest( XPosition &item, // Hold Result ... XPosition &items[] // Source Array ... ) { // int result = -1; // int itemsCount = ArraySize(items); if (itemsCount <= 0) { return result; } // int tmpAge = 0; XPosition tmpItem; for (int i = 0; i < itemsCount; i++) { // XPosition iItem = items[i]; // int iAge = GetAge(iItem); if (iAge >= 0 && (tmpAge == 0 || tmpAge > iAge)) { // tmpAge = iAge; tmpItem = iItem; } } // if (tmpAge >= 0) { // result = tmpAge; item = tmpItem; } // return result; } int GetXYoungest( XPosition &item, // Hold Result ... XPosition &items[] // Source Array ... ) { return GetYoungest(item, items); } // int FindMaxProfitIndex( XPosition &positions[] // Position Collection ) { // int result = -1; // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // double max = 0; for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; if (iPosition.profit <= 0) { continue; } // if (max == 0 || max < iPosition.profit) { // result = i; max = iPosition.profit; } } // return result; } // int FindMinProfitIndex( XPosition &positions[] // Position Collection ) { // int result = -1; // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // double min = 0; for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; if (iPosition.profit <= 0) { continue; } // if (min == 0 || min > iPosition.profit) { // result = i; min = iPosition.profit; } } // return result; } // int ExtractInProfitPositions( XPosition &positions[], // Position Collection XPosition &inProfits[] // Result ) { // int result = 0; // Clean(inProfits); // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.profit > 0) { // AddRef( iPosition, inProfits // ); } } // result = ArraySize(inProfits); // return result; } // int FindMaxDrawdownIndex( XPosition &positions[] // Position Collection ) { // int result = -1; // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // double max = 0; for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; if (iPosition.profit >= 0) { continue; } // if (max == 0 || MathAbs(max) < MathAbs(iPosition.profit)) { // result = i; max = iPosition.profit; } } // return result; } // int FindMinDrawdownIndex( XPosition &positions[] // Position Collection ) { // int result = -1; // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // double min = 0; for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; if (iPosition.profit >= 0) { continue; } // if (min == 0 || min > iPosition.profit) { // result = i; min = iPosition.profit; } } // return result; } // int ExtractInDrawdownPositions( XPosition &positions[], // Position Collection XPosition &inDradowns[] // Result ) { // int result = 0; // Clean(inDradowns); // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.profit < 0) { // AddRef( iPosition, inDradowns // ); } } // result = ArraySize(inDradowns); // return result; } // // Check Filters ... // // Magic Filter ... template bool IsMagicFilterPassed( ulong magic, bool filterByMagic, T &item // ) { // return !filterByMagic ? true : !NotEmpty(magic) ? false : magic == item.magic; } // // Symbol Filter ... template bool IsSymbolFilterPassed( string symbol, T &item // ) { // return !IsValid(symbol) ? true : symbol == item.symbol; } // // Provider Filter ... template bool IsProviderFilterPassed( string provider, T &item // ) { // return !IsValid(provider) ? true : provider == item.provider || Contains(provider, item.provider); } // // Period Filter ... template bool IsPeriodFilterPassed( ENUM_TIMEFRAMES period, T &item // ) { // return !IsValid(period) ? true : period == item.period; } // // Type Filter ... template bool IsTypeFilterPassed( ENUM_POSITION_TYPE type, T &item // ) { // bool result = type == item.type; // return result; } template bool IsTypeFilterPassed( ENUM_X_POSITION_TYPES type, T &item // ) { // bool result = type == NULL || type == X_POSITION_TYPE_ALL ? true : ((type == X_POSITION_TYPE_LONG && ((int)item.type == (int)POSITION_TYPE_BUY || (int)item.type == (int)ORDER_TYPE_BUY)) || (type == X_POSITION_TYPE_SHORT && ((int)item.type == (int)POSITION_TYPE_SELL || (int)item.type == (int)ORDER_TYPE_SELL))); // return result; } template bool IsTypeFilterPassed( ENUM_ORDER_TYPE type, T &item // ) { // return type == NULL ? true : type == item.type; } template bool IsTypeFilterPassed( ENUM_DEAL_TYPE type, T &item // ) { // return type == NULL ? true : type == item.type; } // // Mode Filter ... template bool IsModeFilterPassed( ENUM_X_ORDER_MODES mode, T &item // ) { // return mode == NULL ? true : mode == item.mode; } // // Entry Filter ... template bool IsEntryFilterPassed( ENUM_DEAL_ENTRY entry, T &item // ) { // return entry == NULL ? true : entry == item.entry; } // // Reason Filter ... template bool IsReasonFilterPassed( ENUM_DEAL_REASON reason, T &item // ) { // return reason == NULL ? true : reason == item.reason; } // // State Filter ... template bool IsStateFilterPassed( ENUM_ORDER_STATE state, T &item // ) { // return state == NULL ? true : state == item.state; } // // // // Calculate Positions Profit Summary ... double SpecifiedCalculatePositionsProfit( XPosition &positions[] // Source ) { // double result = 0; // int positionsCount = ArraySize(positions); if (positionsCount <= 0) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // result += iPosition.profit; } // return result; } // // Calculate Required Profit for Hedging ... double SpecifiedCalculateRequiredProfitForHedge( XPosition &positions[], // Source double mMinProfitPerTrade, double mMinProfitPerVolumeFactor // ) { // double result = 0; // int positionsCount = ArraySize(positions); if (positionsCount <= 0) { return result; } // bool isHedgingEnable = mMinProfitPerTrade > 0 && mMinProfitPerVolumeFactor > 0; if (!isHedgingEnable) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (mMinProfitPerTrade > 0 && mMinProfitPerVolumeFactor > 0) { // result += ((iPosition.volume / mMinProfitPerVolumeFactor) * mMinProfitPerTrade) + (-1 * iPosition.swap); } } // return result; } // bool SpecifiedIsPositionsReadyForHedge( XPosition &positions[], // Source double mMinProfitPerTrade, double mMinProfitPerVolumeFactor // ) { // double profit = SpecifiedCalculatePositionsProfit(positions); double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( positions, mMinProfitPerTrade, mMinProfitPerVolumeFactor // ); // bool result = requiredProfit > 0 ? profit >= requiredProfit : profit > requiredProfit; // return result; } // int FindCoverageDrawdownPosition( XPosition &position, // In Drawdown Position XPosition &inProfits[], // In Profit Positions XPosition &coverage[], // Coverage Positons double mMinProfitPerTrade, double mMinProfitPerVolumeFactor // ) { // int result = 0; // Clean(coverage); // if (!position.IsValid() || position.profit >= 0) { return result; } // int inProfitsCount = ArraySize(inProfits); if (!IsValidSize(inProfitsCount)) { return result; } // // Copy in Profits to TMP ... XPosition tmp[]; Copy( inProfits, tmp // ); // bool isCoverPassed = false; while (!isCoverPassed || ArraySize(tmp) > 0) { // XPosition max; int idx = FindMaxProfitIndex(tmp); if (idx >= 0) { // if (tmp[idx].profit > 0) { AddRef( tmp[idx], coverage // ); // ArrayRemove( tmp, idx, 1 // ); } } // // Check Cover Passed ... XPosition tmpPositions[]; Copy( coverage, tmpPositions // ); AddRef( position, tmpPositions // ); // double profits = SpecifiedCalculatePositionsProfit(tmpPositions); double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( tmpPositions, mMinProfitPerTrade, mMinProfitPerVolumeFactor // ); isCoverPassed = profits >= requiredProfit; if (isCoverPassed) { break; } // if (!isCoverPassed && ArraySize(tmp) == 0) { break; } } // result = ArraySize(coverage); // return result; } // // Extract a Collection of Positions SL ... int ExtractSLs( XPosition &positions[], double &sls[] // ) { // int result = 0; // Clean(sls); // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.sl > 0) { // Add( iPosition.sl, sls // ); } } // result = ArraySize(sls); // return result; } // // Extract a Colletion of Positions TP ... int ExtractTPs( XPosition &positions[], double &tps[] // ) { // int result = 0; // Clean(tps); // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // if (iPosition.tp > 0) { // Add( iPosition.tp, tps // ); } } // result = ArraySize(tps); // return result; } // // Retrieve String Representation ... string ToString(ENUM_X_SIGNAL_EXECUTION_RESULT value) { // string result = NULL; // switch (value) { // case X_SIGNAL_EXECUTION_UNKNOWN: result = "Unknown"; break; // case X_SIGNAL_EXECUTION_SUCCEED: result = "Succed"; break; // case X_SIGNAL_EXECUTION_FAILED_SPREAD: result = "Spread more than Max Allowed"; break; // case X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED: result = "not Allowed"; break; // case X_SIGNAL_EXECUTION_FAILED_NO_EQUITY: result = "No Equity for Trade"; break; // case X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR: result = "Price Error"; break; // case X_SIGNAL_EXECUTION_FAILED_PREV_PROFIT_ERROR: result = "Previous Position Profit not Passed for Accept Next"; break; // case X_SIGNAL_EXECUTION_FAILED_MAX_REACHED: result = "Max Allowed Positions Reached"; break; // case X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED: result = "Min Delay Between to Signal not Passed"; break; // case X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS: result = "Invalid Params"; break; } // return result; } // // Converts Position Type to Order Type ... ENUM_ORDER_TYPE ToOrderType(ENUM_POSITION_TYPE value) { // bool isLong = IsLong(value); // ENUM_ORDER_TYPE result = isLong ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; // return result; } ENUM_ORDER_TYPE ToOrderType(ENUM_X_POSITION_TYPES value) { // ENUM_POSITION_TYPE mType = value == X_POSITION_TYPE_SHORT ? POSITION_TYPE_SELL : POSITION_TYPE_BUY; // bool isLong = IsLong(mType); // ENUM_ORDER_TYPE result = isLong ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; // return result; } // // Tagging ... // // Generate Specified Tag for Using in Comments ... string GeneratePeriodTag(ENUM_TIMEFRAMES period) { // string strPeriod = ToXString(period); return Surround( XPeriodToken, strPeriod // ); } // // Extract Period from a Tagged string ... ENUM_TIMEFRAMES ExtractPeriod(string value) { // ENUM_TIMEFRAMES result = NULL; // string pStr = ParseStringSurrounded( value, XPeriodToken // ); if (!IsValid(pStr)) { return result; } // result = ToPeriod(pStr); // return result; } // Generate Specified Tag for Using in Comments ... string GenerateProviderTag(string provider) { // return Surround( XProviderToken, provider // ); } // // Extract Provider from a Tagged string ... string ExtractProvider(string value) { // return ParseStringSurrounded( value, XProviderToken // ); } // // Generate Support Comment Tag ... string GenerateSupportTag(ulong ticket) { // return Surround( XSupportToken, ticket // ); } // // Extract Support Positions from a Tagged string ... ulong ExtractSupportedTicket(string value) { // return ParseLongSurrounded( value, XSupportToken // ); } // // Extract Support ... template int ExtractSupports( T &source[], T &dest[] // Result ... ) { // int result = 0; // Clean(dest); // int sourceCount = ArraySize(source); if (!IsValidSize(sourceCount)) { return result; } // for (int i = 0; i < sourceCount; i++) { // T iSource = source[i]; // ulong isSupport = ExtractSupportedTicket(iSource.comment) > 0; ulong iEQMSupport = ExtractEQMSupportedTicket(iSource.comment) > 0; if (isSupport || iEQMSupport) { // AddRef( iSource, dest // ); } } // result = ArraySize(dest); // return result; } // // Generate EQM Support Comment Tag ... string GenerateEQMSupportTag(ulong ticket) { // return Surround( XEQMSupportToken, ticket // ); } // // Extract EQM Support Positions from a Tagged string ... ulong ExtractEQMSupportedTicket(string value) { // return ParseLongSurrounded( value, XEQMSupportToken // ); } // bool IsSupport(string value) { // bool result = false; // bool isSupport = ExtractSupportedTicket(value) > 0; bool isEQMSupport = ExtractEQMSupportedTicket(value) > 0; // result = // isSupport // || // isEQMSupport // ; // return result; } // ulong ExtractParentTicket(string value) { // ulong result = 0; // if (!IsSupport(value)) { return result; } // result = ExtractSupportedTicket(value); if (result > 0) { return result; } // result = ExtractEQMSupportedTicket(value); // return result; } // // XRecovery ... // string GenerateRecoveryTag(ulong ticket) { // return Surround( XRecoveryToken, ticket // ); } // ulong ExtractRecoveredTicket(string value) { // return ParseLongSurrounded( value, XRecoveryToken // ); } // // Extract Recoveries ... template int ExtractRecoveries( T &source[], T &dest[] // Result ... ) { // int result = 0; // Clean(dest); // int sourceCount = ArraySize(source); if (!IsValidSize(sourceCount)) { return result; } // for (int i = 0; i < sourceCount; i++) { // T iSource = source[i]; // ulong isRecovery = ExtractRecoveredTicket(iSource.comment) > 0; if (isRecovery) { // AddRef( iSource, dest // ); } } // result = ArraySize(dest); // return result; } // // Extract Specified Position's Recoveries ... int ExtractRecoveries( ulong ticket, XPosition &source[], XPosition &dest[] // Result ... ) { // int result = 0; // Clean(dest); // int sourceCount = ArraySize(source); if (!IsValidSize(sourceCount)) { return result; } // for (int i = 0; i < sourceCount; i++) { // XPosition iSource = source[i]; // ulong parentTicket = ExtractRecoveredTicket(iSource.comment); bool isRecovery = parentTicket > 0; if (isRecovery && parentTicket == ticket) { // AddRef( iSource, dest // ); } } // result = ArraySize(dest); // return result; } // // SL Trails ... // // Extract SL Trail Level ... int ExtractSLTrailLevel(string comment) { // int result = 0; // if (!IsValid(comment)) { return result; } // result = ParseIntSurrounded( comment, XSLTrailToken // ); // return result; } // // Generate SL Trail Comment Tag ... string GenerateSLTrailTag(int level) { // string result = NULL; // if (level <= 0) { return result; } // result = Surround( XSLTrailToken, level // ); // return result; } // // Prepare SL Trail Comment ... string PrepareSLTrailTag( const string comment // Original Position Comment ... ) { // string result = NULL; // int level = 0; result = comment; // // Check Comment Contains SL Trailing or not ... int lastTrailLevel = ExtractSLTrailLevel(comment); if (lastTrailLevel <= 0) { level++; } else { // level = lastTrailLevel + 1; string lastLevelStr = GenerateSLTrailTag(lastTrailLevel); StringReplace( result, lastLevelStr, "" // ); } // // Generate level Comment ... string levelStr = GenerateSLTrailTag(level); result += levelStr; // return result; } // // Count Positions from a Collection ... void CountPositions( const XPosition &positions[], int &longs, double &longProfits, double &longVolumes, // // int &shorts, double &shortProfits, double &shortVolumes // ) { // longs = 0; longProfits = 0; longVolumes = 0; // shorts = 0; shortProfits = 0; shortVolumes = 0; // int positionsCount = ArraySize(positions); if (!IsValidSize(positionsCount)) { return; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // bool isLong = IsLong(iPosition.type); if (isLong) { // longs++; longProfits += iPosition.profit; longVolumes += iPosition.volume; } else { // shorts++; shortProfits += iPosition.profit; shortVolumes += iPosition.volume; } } } // // Extract Positions based On Type ... void ExtractPositions( XPosition &positions[], XPosition &longs[], XPosition &shorts[] // ) { // int count = ArraySize(positions); if (!IsValidSize(count)) { return; } // Clean(longs); Clean(shorts); // for (int i = 0; i < count; i++) { // XPosition iPosition = positions[i]; // bool isLong = IsLong(iPosition.type); if (isLong) { AddRef( iPosition, longs // ); } else { AddRef( iPosition, shorts // ); } } } // // Apply a Collection of Targets // on Specified Signal ... void ApplyTargetsOnSignal( ENUM_X_DIRECTION sortingDir, // Target Sorting Direction ... XTarget &targets[], // Required Targets ... XSignal &signal // Destination Signal ... ) { // bool has = HasChild(targets) && HasDirection(sortingDir); if (!has) { return; } // // Sort Targets ... ApplySortOnTargets( sortingDir, targets // ); // // Compare TP with Targets ... int idx = IsLong(signal.type) ? GetHighest(targets) : GetLowest(targets); has = IsValidIndex(idx); if (has) { // // Compare TP ... has = IsLong(signal.type) ? targets[idx].target > signal.tp : targets[idx].target < signal.tp; if (has) { // XTarget tpTarget; tpTarget = targets[idx]; tpTarget.actingDistance = 0; tpTarget.target = signal.tp; // signal.tp = targets[idx].target; targets[idx].actingDistance = 0; // ArrayRemove( targets, idx, 1 // ); // AddRef( tpTarget, targets // ); } // // Sort Targets ... ApplySortOnTargets( sortingDir, targets // ); } // Copy( targets, signal.targets // ); } /** * Select Specified Position's Related Position(s) * for Protecting ... * * @param selecteds: XPosition instance reference Collection, for Holding Selected Positions ... * @param positions: XPosition instance reference Collection, All available source Positions ... * @param forType: ENUM_X_POSITION_TYPES member, Spcified Position Type to Select for it ... * @param selectType: ENUM_XPOSITION_SELECT_TYPES member, Specified Positions Selecting Senario ... * * @return ( bool ) */ bool SelectPosition( XPosition &selecteds[], XPosition &positions[], ENUM_X_POSITION_TYPES forType, ENUM_XPOSITION_SELECT_TYPES selectType // ) { // bool result = false; // // Normalize Args ... Clean(selecteds); // // Validate Args ... result = IsValid(forType) && HasChild(positions) && IsXValid(selectType); if (!result) { return result; } // // Extract Separate Type of Positions ... // int idx = -1; bool has = false; XPosition iPosition; // bool isLong = IsLong(forType); bool isShort = IsShort(forType); int count = ArraySize(positions); // XPosition samePositions[]; XPosition oppositPositions[]; XPosition inProfitPositions[]; XPosition inDrawdownPositions[]; XPosition sameInProfitPositions[]; XPosition sameInDrawdownPositions[]; XPosition oppositInProfitPositions[]; XPosition oppositInDrawdownPositions[]; // for (int i = 0; i < count; i++) { // // Select Indexed Position ... iPosition = positions[i]; // bool isIPosLong = IsLong(iPosition.type); bool isIPosShort = IsShort(iPosition.type); // // Select if Same Type ... bool isSame = (isLong && isIPosLong) || (isShort && isIPosShort); if (isSame) { // AddRef( iPosition, samePositions // ); } // // Select if Opposit Type ... bool isOpposit = (isLong && isIPosShort) || (isShort && isIPosLong); if (isOpposit) { // AddRef( iPosition, oppositPositions // ); } // iPosition.Clean(); } // // Filling Other Requirement Collections ... // ExtractInProfitPositions( positions, inProfitPositions // ); // ExtractInProfitPositions( samePositions, sameInProfitPositions // ); // ExtractInProfitPositions( oppositPositions, oppositInProfitPositions // ); // ExtractInDrawdownPositions( positions, inDrawdownPositions // ); // ExtractInDrawdownPositions( samePositions, sameInDrawdownPositions // ); // ExtractInDrawdownPositions( oppositPositions, oppositInDrawdownPositions // ); // // Implement Selection Senario ... switch (selectType) { // case XPOSITION_SELECT_ALL: // Copy( positions, selecteds // ); break; // case XPOSITION_SELECT_IN_PROFITS: // Copy( inProfitPositions, selecteds // ); break; // case XPOSITION_SELECT_IN_DRAWDOWNS: // Copy( inDrawdownPositions, selecteds // ); break; // case XPOSITION_SELECT_OLDEST: // GetOldest( iPosition, positions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_YOUNGEST: // GetYoungest( iPosition, positions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_PROFITS_OLDEST: // GetOldest( iPosition, inProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_PROFITS_YOUNGEST: // GetYoungest( iPosition, inProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_PROFITS_MIN: // idx = FindMinProfitIndex(inProfitPositions); if (IsValidIndex(idx)) { // iPosition = inProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_PROFITS_MAX: // idx = FindMaxProfitIndex(inProfitPositions); if (IsValidIndex(idx)) { // iPosition = inProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_DRAWDOWN_OLDEST: // GetOldest( iPosition, inDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_DRAWDOWN_YOUNGEST: // GetYoungest( iPosition, inDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_DRAWDOWN_MIN: // idx = FindMinDrawdownIndex(inDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = inDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_IN_DRAWDOWN_MAX: // idx = FindMaxDrawdownIndex(inDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = inDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAMES: // Copy( samePositions, selecteds // ); break; // case XPOSITION_SELECT_SAMES_OLDEST: // GetOldest( iPosition, samePositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAMES_YOUNGEST: // GetYoungest( iPosition, samePositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSITS: // Copy( oppositPositions, selecteds // ); break; // case XPOSITION_SELECT_OPPOSIT_OLDEST: // GetOldest( iPosition, oppositPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSIT_YOUNGEST: // GetYoungest( iPosition, oppositPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_PROFITS: // Copy( sameInProfitPositions, selecteds // ); break; // case XPOSITION_SELECT_SAME_IN_PROFITS_OLDEST: // GetOldest( iPosition, sameInProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_PROFITS_YOUNGEST: // GetYoungest( iPosition, sameInProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_PROFITS_MIN: // idx = FindMinProfitIndex(sameInProfitPositions); if (IsValidIndex(idx)) { // iPosition = sameInProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_PROFITS_MAX: // idx = FindMaxProfitIndex(sameInProfitPositions); if (IsValidIndex(idx)) { // iPosition = sameInProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSIT_IN_PROFITS: // Copy( oppositInProfitPositions, selecteds // ); break; // case XPOSITION_SELECT_OPPOSIT_IN_PROFITS_OLDEST: // GetOldest( iPosition, oppositInProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSIT_IN_PROFITS_YOUNGEST: // GetYoungest( iPosition, oppositInProfitPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSIT_IN_PROFITS_MIN: // idx = FindMinProfitIndex(oppositInProfitPositions); if (IsValidIndex(idx)) { // iPosition = oppositInProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSIT_IN_PROFITS_MAX: // idx = FindMaxProfitIndex(oppositInProfitPositions); if (IsValidIndex(idx)) { // iPosition = oppositInProfitPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_DRAWDOWNS: // Copy( sameInDrawdownPositions, selecteds // ); break; // case XPOSITION_SELECT_SAME_IN_DRAWDOWN_OLDEST: // GetOldest( iPosition, sameInDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_DRAWDOWN_YOUNGEST: // GetYoungest( iPosition, sameInDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_DRAWDOWN_MIN: // idx = FindMinDrawdownIndex(sameInDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = sameInDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_SAME_IN_DRAWDOWN_MAX: // idx = FindMaxDrawdownIndex(sameInDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = sameInDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWNS: // Copy( oppositInDrawdownPositions, selecteds // ); break; // case XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_OLDEST: // GetOldest( iPosition, oppositInDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_YOUNGEST: // GetYoungest( iPosition, oppositInDrawdownPositions // ); if (iPosition.IsValid()) { // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MIN: // idx = FindMinDrawdownIndex(oppositInDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = oppositInDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // case XPOSITION_SELECT_OPPOSITS_IN_DRAWDOWN_MAX: // idx = FindMaxDrawdownIndex(oppositInDrawdownPositions); if (IsValidIndex(idx)) { // iPosition = oppositInDrawdownPositions[idx]; // AddRef( iPosition, selecteds // ); } iPosition.Clean(); break; // } // // Validate Result ... result = HasChild(selecteds); // // Cleanup Resources ... // if (!result) { Clean(selecteds); } // Clean(samePositions); Clean(oppositPositions); Clean(inProfitPositions); Clean(inDrawdownPositions); Clean(sameInProfitPositions); Clean(sameInDrawdownPositions); Clean(oppositInProfitPositions); Clean(oppositInDrawdownPositions); // return result; } //