/////////////////////////////////////////////////////// // // 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 "../Classes/x-saherelm.base.class.mq5" #include // // Definitions ... // // All Available POI(s) ... enum ENUM_XPOIS { // X_POI_NONE, // X_POI_TICKS_ZONES, // Ticks Zone ... // // Trading Day ... X_POI_TRADING_DAY, // Trading Day ... // // Market Session ... X_POI_MARKET_SESSION, // Market Session ... // // Momentum Bar ... X_POI_MOMENTUM_BAR, // Momentum Bar ... // // Rejection Bar ... X_POI_REJECTION_BAR, // Rejection Bar ... // // Swings ... X_POI_SWING_HIGH, // Simple Swing High ... X_POI_SWING_LOW, // Simple Swing Low ... // // Support nad Resistance ... X_POI_SUPPORT_ZONE, // Support Zone ... X_POI_RESISTANCE_ZONE, // Resistance Zone ... // // Supply and Demand Zones ... X_POI_SUPPLY_ZONE, // Supply Zone ... X_POI_DEMAND_ZONE, // Demand Zone ... // // Order Blocks ... X_POI_BULLISH_ORDERBLOCK, // Bullish Order Block ... X_POI_BEARISH_ORDERBLOCK, // Bearish Order Block ... // // Fair Value Gaps ... X_POI_BULLISH_FVG, // Bullish Order Block ... X_POI_BEARISH_FVG, // Bearish Order Block ... // X_BULLISH_CONSOLIDATION_ZONE, X_BEARISH_CONSOLIDATION_ZONE, }; // // Event Types ... enum ENUM_XPOI_EVENTS { // X_POI_EVENT_NONE, // // Trading Days ... X_TRADE_DAY_FIRST_BAR, // Trading Day First Bar ... X_TRADE_DAY_LAST_BAR, // Trading Day Last Bar ... // // Session ... X_SESSION_FIRST_BAR, // Session First Bar ... X_SESSION_LAST_BAR, // Session Last Bar ... // // Momentum Bar ... X_BULLISH_MOMENTUM_BAR_DETECTED, X_BEARISH_MOMENTUM_BAR_DETECTED, // // Rejection Bar ... X_BULLISH_REJECTION_BAR_DETECTED, X_BEARISH_REJECTION_BAR_DETECTED, // // Swings ... X_SWING_HIGH_DETECTED, X_SWING_LOW_DETECTED, // // Support nad Resistance ... X_SUPPORT_ZONE_DETECTED, // Support Zone ... X_RESISTANCE_ZONE_DETECTED, // Resistance Zone ... // // Supply nad Demand ... X_SUPPLY_ZONE_DETECTED, // Supply Zone ... X_DEMAND_ZONE_DETECTED, // Demand Zone ... // // Order Blocks ... X_BULLISH_ORDERBLOCK_DETECTED, // Bullish Order Block ... X_BEARISH_ORDERBLOCK_DETECTED, // Bearish Order Block ... // // Fair Value Gaps ... X_BULLISH_FVG_DETECTED, // Bullish Fair Value Gapّ ... X_BEARISH_FVG_DETECTED, // Bearish Fair Value Gapّ ... X_BULLISH_CONSOLIDATION_ZONE_DETECTED, X_BEARISH_CONSOLIDATION_ZONE_DETECTED, }; // enum ENUM_XZONE_STATE { XZONE_STATE_NONE, XZONE_STATE_PASSED, XZONE_STATE_FAILED, XZONE_STATE_IGNORED, }; // // Forext Sessions ... enum ENUM_XSESSION { X_TOKYO, X_SYDNEY, X_LONDON, X_NEW_YORK, X_FRANKFORT, }; /** * Converts ENUM_XPOI value to String Representation ... * * @param value: ENUM_XPOI member ... * * @return ( string ) */ string ToString(ENUM_XPOIS value) { // string result = NULL; // switch (value) { // case X_POI_TRADING_DAY: result = "XTDAY"; break; // case X_POI_MARKET_SESSION: result = "XMSESS"; break; // case X_POI_MOMENTUM_BAR: result = "XMNTMB"; break; // case X_POI_REJECTION_BAR: result = "XRJCTB"; break; // case X_POI_SWING_HIGH: result = "XSPH"; break; // case X_POI_SWING_LOW: result = "XSPL"; break; // case X_POI_SUPPORT_ZONE: result = "XSUP"; break; // case X_POI_RESISTANCE_ZONE: result = "XRES"; break; // case X_POI_SUPPLY_ZONE: result = "XSUPPLY"; break; // case X_POI_DEMAND_ZONE: result = "XDEMAND"; break; // case X_POI_BULLISH_ORDERBLOCK: result = "XBULLOB"; break; // case X_POI_BEARISH_ORDERBLOCK: result = "XBEAROB"; break; // case X_POI_BULLISH_FVG: result = "XBULLFVG"; break; // case X_POI_BEARISH_FVG: result = "XBEARFVG"; break; // case X_POI_TICKS_ZONES: result = "XTKSZ"; break; // case X_BULLISH_CONSOLIDATION_ZONE: result = "XBULLCZ"; break; // case X_BEARISH_CONSOLIDATION_ZONE: result = "XBEARCZ"; break; } // return result; } /** * Converts ENUM_XSESSION value to String Representation ... * * @param value: ENUM_XSESSION member ... * * @return ( string ) */ string ToString(ENUM_XSESSION value) { // string result = NULL; // switch (value) { // case X_SYDNEY: result = "Sydney"; break; // case X_TOKYO: result = "Tokyo"; break; // case X_FRANKFORT: result = "FrankGurt"; break; // case X_LONDON: result = "London"; break; // case X_NEW_YORK: result = "NewYork"; break; } // return result; } /** * Generate General Event Messages ... * * @param value: ENUM_XPOI_EVENTS member ... * * @return ( string ) */ string ToString(ENUM_XPOI_EVENTS value) { // string result = NULL; // switch (value) { // case X_TRADE_DAY_FIRST_BAR: result = "First Bar of Day"; break; // case X_TRADE_DAY_LAST_BAR: result = "Last Bar of Day"; break; // case X_SESSION_FIRST_BAR: result = "First Bar of Session"; break; // case X_SESSION_LAST_BAR: result = "Last Bar of Session"; break; // case X_BULLISH_MOMENTUM_BAR_DETECTED: result = "Bullish Momentum Bar Detected"; break; // case X_BEARISH_MOMENTUM_BAR_DETECTED: result = "Bearish Momentum Bar Detected"; break; // case X_BULLISH_REJECTION_BAR_DETECTED: result = "Bullish Rejection Bar Detected"; break; // case X_BEARISH_REJECTION_BAR_DETECTED: result = "Bearish Rejection Bar Detected"; break; // case X_SWING_HIGH_DETECTED: result = "Swing High Detected"; break; // case X_SWING_LOW_DETECTED: result = "Swing Low Detected"; break; // case X_SUPPORT_ZONE_DETECTED: result = "Support Zone Detected"; break; // case X_RESISTANCE_ZONE_DETECTED: result = "Resistance Zone Detected"; break; // case X_SUPPLY_ZONE_DETECTED: result = "Supply Zone Detected"; break; // case X_DEMAND_ZONE_DETECTED: result = "Demand Zone Detected"; break; // case X_BULLISH_ORDERBLOCK_DETECTED: result = "Bullish Order Block Detected"; break; // case X_BEARISH_ORDERBLOCK_DETECTED: result = "Bearish Orer Block Detected"; break; // case X_BULLISH_FVG_DETECTED: result = "Bullish FVG Detected"; break; // case X_BEARISH_FVG_DETECTED: result = "Bearish FVg Detected"; break; } // return result; } // // Implementation ... // // Base POI Model Class ... class XCBasePOI : public XCBase { // public: // // // Constructor ... void XCBasePOI() { // Clean(); // mSep = "_"; mLineSep = "\n"; } // // Deconstructor ... void ~XCBasePOI() { Clean(); } // // Virtual ... /** * Cleanup ... */ virtual void Clean() { mType = X_POI_NONE; } /** * Validate ... * * @return ( virtual bool ) */ virtual bool IsValid() { return false; } /** * Retrieve POI Type ... * * @return ( virtual ENUM_XPOIS member ) */ virtual ENUM_XPOIS Type() { return mType; } /** * Retrieve POI Type ... * * @return ( virtual string ) */ virtual string TypeAsString() { return ToString(mType); } /** * Retrieve POI Tag ... * * @return ( virtual string ) */ virtual string GetTag() { return NULL; } /** * Retrieve POI Tooltip ... * * @return ( virtual string ) */ virtual string GetTooltip() { return NULL; } // protected: // // Props ... string mSep; // Separator ... string mLineSep; // Line Separator ... ENUM_XPOIS mType; // Type ... // private: // }; // typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, XCBasePOI *param // ); // // Zone POI Class ... class XCZone : public XCBasePOI { // public: // // // Constructor ... void XCZone() { } // // Deconstructor ... void ~XCZone() { } // // Tools ... // // Getter(s) / Setter(s) ... /** * Get Zone Upper Boundary ... * * @return ( double ) */ double Upper() { return mUpper; } /** * Set Zone Upper Boundary ... */ void Upper(double value) { mUpper = value; } /** * Get Zone Lower Boundary ... * * @return ( double ) */ double Lower() { return mLower; } /** * Set Zone Lower Boundary ... */ void Lower(double value) { mLower = value; } /** * Retrieve Zone Range ... * * @return ( double ) */ double Range() { // double result = 0; // double upper = Upper(); double lower = Lower(); // if (upper > 0 && lower > 0 && upper > lower) { result = upper - lower; } // return result; } double RangePercent() { // double result = 0; // double range = Range(); if (range > 0) { result = range / 100; } // return result; } // // Virtuals ... /** * Get Zone Start Date ... * * @return ( virtual datetime ) */ virtual datetime From() { return NULL; } /** * Get Zone End Date ... * * @return ( virtual datetime ) */ virtual datetime To() { return NULL; } // // Getter(s) / Setter(s) ... // // Overrides ... // // Validators ... /** * Validate Upper and Lower of Zone ... * * @return ( bool ) */ bool IsValidBoundary() { // bool result = false; // result = // mUpper > 0 && mLower > 0 && mUpper >= mLower // ; // return result; } /** * Check From Date of Zone is Valid ... * * @return ( bool ) */ bool IsValidFrom() { // bool result = false; // datetime from = From(); result = IsSpecifiedValid(from); // return result; } // protected: // // Props ... double mUpper; // Zone Upper ... double mLower; // Zone Lower ... // private: // // Props ... // }; // // From To Zone ... class XCFromToZone : public XCBasePOI { // public: // // // Constructor ... void XCFromToZone() { } // // Deconstructor ... void ~XCFromToZone() { } // // Tools ... bool InitFromTo( ENUM_XPOIS type, string title, datetime from // ) { // bool result = false; // result = type != X_POI_NONE && IsSpecifiedValid(from) && IsSpecifiedValid(title); // mType = type; mFrom = from; mTitle = title; mTo = TimeCurrent(); // result = IsValid(); // return result; } bool InitFromTo( ENUM_XPOIS type, string title, datetime from, datetime to // ) { // bool result = false; // result = IsValid(); // result = InitFromTo( type, title, from // ); if (!result) { return result; } // to = NormalizeTime(to); mTo = to; // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Get Zone Start Time ... * * @return ( datetime ) */ datetime From() { return mFrom; } /** * Set Zone Start Time ... * * @param value: Datetime */ void From(datetime value) { // value = NormalizeTime(value); // mFrom = value; } /** * Get Zone End Time ... * * @return ( datetime ) */ datetime To() { return mTo; } /** * Set Zone End Time ... * * @param value: Datetime */ void To(datetime value) { // value = NormalizeTime(value); // mTo = value; } /** * Get Title ... * * @return ( string ) */ string Title() { return mTitle; } /** * Set Title ... * * @param value: String ... */ // void Title(string value) // { // mTitle = value; // } // // Overrides ... void Clean() override { // mTo = NULL; mFrom = NULL; mType = X_POI_NONE; } bool IsValid() override { // bool result = false; // result = // mType != X_POI_NONE && IsSpecifiedValid(mTo) && IsSpecifiedValid(mFrom) && IsSpecifiedValid(mTitle) // ; // return result; } string GetTag() override { // string result = NULL; // if (!IsValid()) { return result; } // string hash = TypeAsString() + mSep + ToString(From()) + mSep + Title(); hash = ToMD5(hash); // result = TypeAsString() + "[" + Title() + "]" + mSep + hash; // return result; } // protected: // // private: // // Props ... datetime mFrom; // Start Date datetime mTo; // End Date string mTitle; // Zone Title // }; // // Bar Zone ... class XCBarZone : public XCZone { // public: // // // Constructor ... void XCBarZone() { } // // Deconstructor ... void ~XCBarZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param type: ENUM_XPOIS member ... * @param upperPrice: ENUM_X_PRICE member ... * @param lowerPrice: ENUM_X_PRICE member ... * * @return ( bool ) */ bool InitBarZone( XOHCL &bar, ENUM_XPOIS type, ENUM_X_PRICE upperPrice, ENUM_X_PRICE lowerPrice // ) { // bool result = false; // result = bar.IsValid() && type != X_POI_NONE && upperPrice != lowerPrice; if (!result) { return result; } // mBar = bar; mType = type; mUpperPrice = upperPrice; mLowerPrice = lowerPrice; mUpper = bar.GetPrice(upperPrice); mLower = bar.GetPrice(lowerPrice); // result = IsValidBarZone(); if (result) { // From(bar.time); To(TimeCurrent()); } // return result; } // // Getter(s) / Setter(s) ... /** * Fill Bar as XOHCL struct ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool FillBar( XOHCL &bar // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // bar = mBar; result = mBar.IsValid(); // return result; } /** * Set From Date ... * * @param value: DateTime ... */ void From(datetime value) { // if (!IsValidBarZone()) { return; } // value = NormalizeTime(value); // mFrom = value; } /** * Set To Date ... * * @param value: DateTime ... */ void To(datetime value) { // if (!IsValidBarZone()) { return; } // value = NormalizeTime(value); // mTo = value; } /** * Retrieve Bar Time ... * * @return ( datetime ) */ datetime BarTime() { return mBar.time; } /** * Get Symbol ... * * @return ( string ) */ string GetSymbol() { // string result = NULL; // if (!mBar.IsValid()) { return result; } // return mBar.symbol; // return result; } /** * Get Period ... * * @return ( int ) */ ENUM_TIMEFRAMES GetPeriod() { // ENUM_TIMEFRAMES result = NULL; // if (!mBar.IsValid()) { return result; } // return mBar.period; // return result; } /** * Check Zone Started or not ... * First Exit in Direction of Zone after From ... * * @param forDir: exit direction ... * @param startedBar: specified Start Bar ... * @param isBodyOut: specified Start Bar Close is Out of Zone or not ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsStarted( ENUM_X_DIRECTION forDir, XOHCL &startedBar, bool &isBodyOut, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; startedBar.Clean(); // result = HasDirection(forDir) && IsValidBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // // Detect From Bar Index ... int fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && isBullish ? isBreakedFromUpper : isBreakedFromLower; if (result) { // startedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = startedBar.IsValid(); if (result) { // isBodyOut = isBullish ? startedBar.IsBullish() && startedBar.GetUp() > Upper() : startedBar.IsBearish() && startedBar.GetDown() < Lower(); } // return result; } /** * Check Zone Activated or not ... * First Enter in Opposit Direction of Zone after Start ... * * @param forDir: exit direction ... * @param activatedBar: specified Activation Bar ... * @param isBodyIn: specified Activation Bar Close is Inside of Zone or not ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsActivated( ENUM_X_DIRECTION forDir, XOHCL &activatedBar, bool &isBodyIn, bool forceBodyOutStarted = true, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyIn = false; activatedBar.Clean(); // result = HasDirection(forDir) && IsValidBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // XOHCL startedBar; bool isBodyOut = false; bool isStarted = IsStarted( forDir, startedBar, isBodyOut, forPeriod // ); result = !forceBodyOutStarted ? isStarted : isStarted && isBodyOut; if (!result) { // startedBar.Clean(); return result; } // int fromIndex = startedBar.Index() - 1; // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isInsideFromUpper = // iBar.high < Upper() || (iBar.high > Upper() && iBar.low <= Upper() && iBar.close <= Upper()) // ; // bool isInsideFromLower = // iBar.low > Lower() || (iBar.low < Lower() && iBar.high >= Lower() && iBar.close >= Lower()) // ; // bool isInside = isInsideFromUpper || isInsideFromLower; if (isInside) { // result = isInside && isBullish ? isInsideFromUpper : isInsideFromLower; if (result) { // activatedBar = iBar; iBar.Clean(); startedBar.Clean(); break; } } // iBar.Clean(); startedBar.Clean(); } // result = activatedBar.IsValid(); if (result) { // isBodyIn = isBullish ? activatedBar.IsBearish() && activatedBar.GetDown() < Upper() : activatedBar.IsBullish() && activatedBar.GetUp() > Lower(); } // return result; } /** * Check Zone Breaked or not ... * * @param forDir: exit direction ... * @param breakedBar: specified Breaked Bar ... * @param isBodyOut: specified Breaked Bar Close is Out of Zone or not ... * @param ignoreStart: Ignore Zone Start (Calculate from From()) ... * @param startedBodyOut: Started Bar Body Close State, if use Start for Calculation ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsBreaked( ENUM_X_DIRECTION forDir, XOHCL &breakedBar, bool &isBodyOut, bool ignoreStart = false, bool startedBodyOut = false, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; breakedBar.Clean(); // result = HasDirection(forDir) && IsValidBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // int fromIndex = -1; if (!ignoreStart) { // XOHCL startedBar; bool isBodyOut = false; bool isStarted = IsStarted( forDir, startedBar, isBodyOut, forPeriod // ); // bool isStartPassed = !startedBodyOut ? isStarted : isStarted && isBodyOut; if (isStartPassed) { fromIndex = startedBar.Index() - 1; } // startedBar.Clean(); } else { // fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); } // result = IsValidIndex(fromIndex); if (!result) { return result; } // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && (isBullish ? isBreakedFromLower : isBreakedFromUpper); if (result) { // breakedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = breakedBar.IsValid(); if (result) { // isBodyOut = isBullish ? breakedBar.IsBearish() && breakedBar.GetDown() < Lower() : breakedBar.IsBullish() && breakedBar.GetUp() > Upper(); } // return result; } /** * Check Zone Worked or not ... * * @param forDir: exit direction ... * @param workedBar: specified Worked Bar ... * @param isBodyOut: specified Worked Bar Close is Out of Zone or not ... * @param ignoreActivation: Ignore Zone Activation (Calculate from From()) ... * @param activationStartedOut: Specified Zone Start Bar State ... * @param activationBodyIn: Specified Zone Activation Bar State ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsWorked( ENUM_X_DIRECTION forDir, XOHCL &workedBar, bool &isBodyOut, bool ignoreActivation = false, bool activationStartedOut = false, bool activationBodyIn = false, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; workedBar.Clean(); // result = HasDirection(forDir) && IsValidBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // int fromIndex = -1; if (!ignoreActivation) { // XOHCL activatedBar; bool isBodyIn = false; bool isActivated = IsActivated( forDir, activatedBar, isBodyIn, activationStartedOut, forPeriod // ); // bool isActivationPassed = !activationBodyIn ? isActivated : isActivated && isBodyIn; if (isActivationPassed) { fromIndex = activatedBar.Index() - 1; } // activatedBar.Clean(); } else { // fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); } // result = IsValidIndex(fromIndex); if (!result) { return result; } // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && isBullish ? isBreakedFromUpper : isBreakedFromLower; if (result) { // workedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = workedBar.IsValid(); if (result) { // isBodyOut = isBullish ? workedBar.IsBullish() && workedBar.GetUp() > Upper() : workedBar.IsBearish() && workedBar.GetDown() < Lower(); } // return result; } /** * Check to Find Nearest Bar which Breakes Upper ... * * @param bar: XOHCL instance Reference, Breaker Bar ... * @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ... * * @return ( bool ) */ bool FindNearestInsideBarFromUpper( XOHCL &bar, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // bar.Clean(); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // result = IsValid(); if (!result) { return result; } // int from = 1; int to = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = from; i < to; i++) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); if (!isInited) { break; } // bool isInside = iBar.low < Upper(); if (isInside) { // bar = iBar; break; } } // result = bar.IsValid(); // return result; } /** * Check to Find Nearest Bar which Breakes Lower ... * * @param bar: XOHCL instance Reference, Breaker Bar ... * @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ... * * @return ( bool ) */ bool FindNearestInsideBarFromLower( XOHCL &bar, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // bar.Clean(); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // result = IsValid(); if (!result) { return result; } // int from = 1; int to = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = from; i < to; i++) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); if (!isInited) { break; } // bool isInside = iBar.high > Lower(); if (isInside) { // bar = iBar; break; } } // result = bar.IsValid(); // return result; } // // Overrides ... void Clean() override { // mBar.Clean(); mUpper = 0; mLower = 0; mType = X_POI_NONE; } datetime From() override { return mFrom; } datetime To() override { return mTo; } string GetTag() override { // string result = NULL; // if (!IsValidBarZone()) { return result; } // string hash = ToMD5(mBar.GetTag()); // result = // TypeAsString() + mSep + ToString(mBar.period) + mSep + hash // ; // return result; } string GetTooltip() override { // string result = NULL; // if (!IsValidBarZone()) { return result; } // return result; } // protected: // // Props ... XOHCL mBar; // Bar ... ENUM_X_PRICE mUpperPrice; // Upper Price Selection ENUM_X_PRICE mLowerPrice; // Lower Price Selection /** * Check Bar Zone Validation ... * * @return ( bool ) */ bool IsValidBarZone() { // bool result = false; // result = mBar.IsValid() && mType != X_POI_NONE && IsValidBoundary(); // return result; } // private: // // Props ... datetime mFrom; datetime mTo; // }; class XCTwoBarZone : public XCZone { // public: // // // Constructor ... void XCTwoBarZone() { } // // Deconstructor ... void ~XCTwoBarZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param type: ENUM_XPOIS member ... * @param upperPrice: ENUM_X_PRICE member ... * @param lowerPrice: ENUM_X_PRICE member ... * * @return ( bool ) */ bool InitTwoBarZone( XOHCL &startBar, XOHCL &endBar, ENUM_XPOIS type, bool useStartBarForUpper, ENUM_X_PRICE upperPrice, ENUM_X_PRICE lowerPrice // ) { // bool result = false; // result = startBar.IsValid() && endBar.IsValid() && startBar.symbol == endBar.symbol && startBar.period == endBar.period && startBar.time < endBar.time && type != X_POI_NONE; if (!result) { return result; } // mType = type; mEndBar = endBar; mStartBar = startBar; mUpperPrice = upperPrice; mLowerPrice = lowerPrice; mUseStartBarForUpper = useStartBarForUpper; mUpper = useStartBarForUpper ? startBar.GetPrice(upperPrice) : endBar.GetPrice(upperPrice); mLower = useStartBarForUpper ? endBar.GetPrice(lowerPrice) : startBar.GetPrice(lowerPrice); // result = IsValidTwoBarZone(); if (result) { // From(startBar.time); To(endBar.time); } // return result; } // // Getter(s) / Setter(s) ... /** * Set From Date ... * * @param value: DateTime ... */ void From(datetime value) { // if (!IsValidTwoBarZone()) { return; } // value = NormalizeTime(value); // mFrom = value; } /** * Set To Date ... * * @param value: DateTime ... */ void To(datetime value) { // if (!IsValidTwoBarZone()) { return; } // value = NormalizeTime(value); // mTo = value; } /** * Fill Start Bar ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool FillStartBar(XOHCL &bar) { // bool result = false; // result = IsValidTwoBarZone(); if (!result) { return result; } // bar = mStartBar; // return result; } /** * Fill End Bar ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool FillEndBar(XOHCL &bar) { // bool result = false; // result = IsValidTwoBarZone(); if (!result) { return result; } // bar = mEndBar; // return result; } /** * Get Symbol ... * * @return ( string ) */ string GetSymbol() { // string result = NULL; // if (!mStartBar.IsValid()) { return result; } // return mStartBar.symbol; // return result; } /** * Get Period ... * * @return ( int ) */ ENUM_TIMEFRAMES GetPeriod() { // ENUM_TIMEFRAMES result = NULL; // if (!mStartBar.IsValid()) { return result; } // return mStartBar.period; // return result; } /** * Check Zone Started or not ... * First Exit in Direction of Zone after From ... * * @param forDir: exit direction ... * @param startedBar: specified Start Bar ... * @param isBodyOut: specified Start Bar Close is Out of Zone or not ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsStarted( ENUM_X_DIRECTION forDir, XOHCL &startedBar, bool &isBodyOut, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; startedBar.Clean(); // result = HasDirection(forDir) && IsValidTwoBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // // Detect From Bar Index ... int fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && isBullish ? isBreakedFromUpper : isBreakedFromLower; if (result) { // startedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = startedBar.IsValid(); if (result) { // isBodyOut = isBullish ? startedBar.IsBullish() && startedBar.GetUp() > Upper() : startedBar.IsBearish() && startedBar.GetDown() < Lower(); } // return result; } /** * Check Zone Activated or not ... * First Enter in Opposit Direction of Zone after Start ... * * @param forDir: exit direction ... * @param activatedBar: specified Activation Bar ... * @param isBodyIn: specified Activation Bar Close is Inside of Zone or not ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsActivated( ENUM_X_DIRECTION forDir, XOHCL &activatedBar, bool &isBodyIn, bool forceBodyOutStarted = true, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyIn = false; activatedBar.Clean(); // result = HasDirection(forDir) && IsValidTwoBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // XOHCL startedBar; bool isBodyOut = false; bool isStarted = IsStarted( forDir, startedBar, isBodyOut, forPeriod // ); result = !forceBodyOutStarted ? isStarted : isStarted && isBodyOut; if (!result) { // startedBar.Clean(); return result; } // int fromIndex = startedBar.Index() - 1; // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isInsideFromUpper = // iBar.high < Upper() || (iBar.high > Upper() && iBar.low <= Upper() && iBar.close <= Upper()) // ; // bool isInsideFromLower = // iBar.low > Lower() || (iBar.low < Lower() && iBar.high >= Lower() && iBar.close >= Lower()) // ; // bool isInside = isInsideFromUpper || isInsideFromLower; if (isInside) { // result = isInside && isBullish ? isInsideFromUpper : isInsideFromLower; if (result) { // activatedBar = iBar; iBar.Clean(); startedBar.Clean(); break; } } // iBar.Clean(); startedBar.Clean(); } // result = activatedBar.IsValid(); if (result) { // isBodyIn = isBullish ? activatedBar.IsBearish() && activatedBar.GetDown() < Upper() : activatedBar.IsBullish() && activatedBar.GetUp() > Lower(); } // return result; } /** * Check Zone reaked or not ... * * @param forDir: exit direction ... * @param breakedBar: specified Breaked Bar ... * @param isBodyOut: specified Breaked Bar Close is Out of Zone or not ... * @param ignoreStart: Ignore Zone Start (Calculate from From()) ... * @param startedBodyOut: Started Bar Body Close State, if use Start for Calculation ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsBreaked( ENUM_X_DIRECTION forDir, XOHCL &breakedBar, bool &isBodyOut, bool ignoreStart = false, bool startedBodyOut = false, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; breakedBar.Clean(); // result = HasDirection(forDir) && IsValidTwoBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // int fromIndex = -1; if (!ignoreStart) { // XOHCL startedBar; bool isBodyOut = false; bool isStarted = IsStarted( forDir, startedBar, isBodyOut, forPeriod // ); // bool isStartPassed = !startedBodyOut ? isStarted : isStarted && isBodyOut; if (isStartPassed) { fromIndex = startedBar.Index() - 1; } // startedBar.Clean(); } else { // fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); } // result = IsValidIndex(fromIndex); if (!result) { return result; } // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && (isBullish ? isBreakedFromLower : isBreakedFromUpper); if (result) { // breakedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = breakedBar.IsValid(); if (result) { // isBodyOut = isBullish ? breakedBar.IsBearish() && breakedBar.GetDown() < Lower() : breakedBar.IsBullish() && breakedBar.GetUp() > Upper(); } // return result; } /** * Check Zone Worked or not ... * * @param forDir: exit direction ... * @param workedBar: specified Worked Bar ... * @param isBodyOut: specified Worked Bar Close is Out of Zone or not ... * @param ignoreActivation: Ignore Zone Activation (Calculate from From()) ... * @param activationStartedOut: Specified Zone Start Bar State ... * @param activationBodyIn: Specified Zone Activation Bar State ... * @param forPeriod: specified Period ... * * @return ( bool ) */ bool IsWorked( ENUM_X_DIRECTION forDir, XOHCL &workedBar, bool &isBodyOut, bool ignoreActivation = false, bool activationStartedOut = false, bool activationBodyIn = false, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // isBodyOut = false; workedBar.Clean(); // result = HasDirection(forDir) && IsValidTwoBarZone(); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // int fromIndex = -1; if (!ignoreActivation) { // XOHCL activatedBar; bool isBodyIn = false; bool isActivated = IsActivated( forDir, activatedBar, isBodyIn, activationStartedOut, forPeriod // ); // bool isActivationPassed = !activationBodyIn ? isActivated : isActivated && isBodyIn; if (isActivationPassed) { fromIndex = activatedBar.Index() - 1; } // activatedBar.Clean(); } else { // fromIndex = iBarShift( GetSymbol(), forPeriod, From() // ); } // result = IsValidIndex(fromIndex); if (!result) { return result; } // for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); result = isInited; if (!result) { // iBar.Clean(); continue; } // bool isBreakedFromUpper = // iBar.low > Upper() || (iBar.low <= Upper() && iBar.high > Upper() && iBar.close > Upper()) // ; // bool isBreakedFromLower = // iBar.low < Lower() || (iBar.high >= Lower() && iBar.low < Lower() && iBar.close < Lower()) // ; // bool isBreaked = isBreakedFromUpper || isBreakedFromLower; if (isBreaked) { // result = isBreaked && isBullish ? isBreakedFromUpper : isBreakedFromLower; if (result) { // workedBar = iBar; iBar.Clean(); break; } } // iBar.Clean(); } // result = workedBar.IsValid(); if (result) { // isBodyOut = isBullish ? workedBar.IsBullish() && workedBar.GetUp() > Upper() : workedBar.IsBearish() && workedBar.GetDown() < Lower(); } // return result; } /** * Check to Find Nearest Bar which Breakes Upper ... * * @param bar: XOHCL instance Reference, Breaker Bar ... * @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ... * * @return ( bool ) */ bool FindNearestInsideBarFromUpper( XOHCL &bar, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // bar.Clean(); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // result = IsValid(); if (!result) { return result; } // int from = 1; int to = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = from; i < to; i++) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); if (!isInited) { break; } // bool isInside = iBar.low < Upper(); if (isInside) { // bar = iBar; break; } } // result = bar.IsValid(); // return result; } /** * Check to Find Nearest Bar which Breakes Lower ... * * @param bar: XOHCL instance Reference, Breaker Bar ... * @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ... * * @return ( bool ) */ bool FindNearestInsideBarFromLower( XOHCL &bar, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // bar.Clean(); // if (!IsSpecifiedValid(forPeriod)) { forPeriod = GetPeriod(); } // result = IsValid(); if (!result) { return result; } // int from = 1; int to = iBarShift( GetSymbol(), forPeriod, From() // ); // for (int i = from; i < to; i++) { // XOHCL iBar; bool isInited = iBar.Init( GetSymbol(), forPeriod, i // ); if (!isInited) { break; } // bool isInside = iBar.high > Lower(); if (isInside) { // bar = iBar; break; } } // result = bar.IsValid(); // return result; } // // Overrides ... void Clean() override { // mStartBar.Clean(); mEndBar.Clean(); mUpper = 0; mLower = 0; mUseStartBarForUpper = false; mType = X_POI_NONE; } datetime From() override { return mFrom; } datetime To() override { return mTo; } string GetTag() override { // string result = NULL; // if (!IsValidTwoBarZone()) { return result; } // string hash = ToMD5(mStartBar.GetTag() + mSep + mEndBar.GetTag()); // result = // TypeAsString() + mSep + ToString(mStartBar.period) + mSep + hash // ; // return result; } string GetTooltip() override { // string result = NULL; // if (!IsValidTwoBarZone()) { return result; } // return result; } // protected: // // Props ... XOHCL mStartBar; // Start (Oldest) Bar ... XOHCL mEndBar; // End (Newest) Bar ... bool mUseStartBarForUpper; // Use Start Bar for Upper Calculation ... ENUM_X_PRICE mUpperPrice; // Upper Price Selection ENUM_X_PRICE mLowerPrice; // Lower Price Selection /** * Check Two Bar Zone Validation ... * * @return ( bool ) */ bool IsValidTwoBarZone() { // bool result = false; // result = mStartBar.IsValid() && mEndBar.IsValid() && mStartBar.symbol == mEndBar.symbol && mStartBar.period == mEndBar.period && mStartBar.time < mEndBar.time && mType != X_POI_NONE && IsValidBoundary(); // return result; } // private: // // Props ... datetime mFrom; datetime mTo; // }; // // Swing Class ... class XCSwing : public XCBasePOI { // public: // // // Constructor ... void XCSwing() { } // // Deconstructor ... void ~XCSwing() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param type: ENUM_XPOIS member ... * * @return ( bool ) */ bool Init( XOHCL &bar, ENUM_XPOIS type // ) { // bool result = false; // result = bar.IsValid() && (type == X_POI_SWING_HIGH || type == X_POI_SWING_LOW); if (!result) { return result; } // mBar = bar; mType = type; // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Fill Bar as XOHCL struct ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool FillBar( XOHCL &bar // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // bar = mBar; result = mBar.IsValid(); // return result; } /** * Get Time of Swing ... * * @return ( datetime ) */ datetime GetTime() { // datetime result = NULL; // if (!IsValid() || !mBar.IsValid()) { return result; } // result = mBar.time; // return result; } ENUM_TIMEFRAMES GetPeriod() { // ENUM_TIMEFRAMES result = NULL; // XOHCL bar; bool isFilled = FillBar(bar); if (!isFilled) { return result; } // result = bar.period; // return result; } /** * Check Swing High or not ... * * @return ( bool ) */ bool IsSwingHigh() { // bool result = false; // result = IsValid(); if (!result) { return result; } // result = Type() == X_POI_SWING_HIGH; // return result; } /** * Check Swing Low or not ... * * @return ( bool ) */ bool IsSwingLow() { // bool result = false; // result = IsValid(); if (!result) { return result; } // result = Type() == X_POI_SWING_LOW; // return result; } /** * Get Swing Value ... * * @return ( double ) */ double GetValue() { // double result = 0; // if (!IsValid()) { return result; } // result = IsSwingHigh() ? mBar.high : mBar.low; // return result; } // // Overrides ... void Clean() override { // mBar.Clean(); mType = X_POI_NONE; } bool IsValid() override { // bool result = false; // result = mBar.IsValid() && (mType == X_POI_SWING_HIGH || mType == X_POI_SWING_LOW); // return result; } string GetTag() override { // string result = NULL; // if (!IsValid()) { return result; } // string hash = ToMD5(mBar.GetTag()); // string subType = IsSwingHigh() ? "High" : "Low"; // result = // TypeAsString() + mSep + subType + mSep + ToString(mBar.period) + mSep + hash // ; // return result; } string GetTooltip() override { // string result = NULL; // if (!IsValid()) { return result; } // return result; } // protected: // // Props ... XOHCL mBar; // Swing Bar ... // private: // }; // // Supply Zone ... class XCSupplyZone : public XCBarZone { // public: // // // Constructor ... void XCSupplyZone() { } // // Deconstructor ... void ~XCSupplyZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param range: Integer, Detection Range ... * * @return ( bool ) */ bool Init( XOHCL &bar, int range = 0, bool useRangeAsStart = false // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // result = InitBarZone( bar, X_POI_SUPPLY_ZONE, X_PRICE_HIGH, X_PRICE_LOW // ); if (!result) { return result; } // result = IsValid(); if (result && range > 0) { // datetime time = bar.time; int periodSeconds = PeriodSeconds(bar.period); // datetime from = !useRangeAsStart ? (datetime)((int)time - (range * periodSeconds)) : time; datetime to = (datetime)((int)time + (range * periodSeconds)); // From(from); To(to); } // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_SUPPLY_ZONE; // return result; } // protected: // // private: // // }; // // Demand Zone ... class XCDemandZone : public XCBarZone { // public: // // // Constructor ... void XCDemandZone() { } // // Deconstructor ... void ~XCDemandZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param range: Integer, Detection Range ... * * @return ( bool ) */ bool Init( XOHCL &bar, int range = 0, bool useRangeAsStart = false // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // result = InitBarZone( bar, X_POI_DEMAND_ZONE, X_PRICE_HIGH, X_PRICE_LOW // ); if (!result) { return result; } // result = IsValid(); if (result && range > 0) { // datetime time = bar.time; int periodSeconds = PeriodSeconds(bar.period); // datetime from = !useRangeAsStart ? (datetime)((int)time - (range * periodSeconds)) : time; datetime to = (datetime)((int)time + (range * periodSeconds)); // From(from); To(to); } // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_DEMAND_ZONE; // return result; } // protected: // // private: // // }; // // Support Zone ... class XCSupportZone : public XCBarZone { // public: // // // Constructor ... void XCSupportZone() { } // // Deconstructor ... void ~XCSupportZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param range: Integer, Detection Range ... * * @return ( bool ) */ bool Init( XOHCL &bar, int range = 0, bool useRangeAsStart = false // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // result = InitBarZone( bar, X_POI_SUPPORT_ZONE, X_PRICE_DOWN, X_PRICE_LOW // ); if (!result) { return result; } // result = IsValid(); if (result && range > 0) { // datetime time = bar.time; int periodSeconds = PeriodSeconds(bar.period); // datetime from = !useRangeAsStart ? (datetime)((int)time - (range * periodSeconds)) : time; datetime to = (datetime)((int)time + (range * periodSeconds)); // From(from); To(to); } // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_SUPPORT_ZONE; // return result; } // protected: // // private: // // }; // // Resistance Zone ... class XCResistanceZone : public XCBarZone { // public: // // // Constructor ... void XCResistanceZone() { } // // Deconstructor ... void ~XCResistanceZone() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param range: Integer, Detection Range ... * * @return ( bool ) */ bool Init( XOHCL &bar, int range = 0, bool useRangeAsStart = false // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // result = InitBarZone( bar, X_POI_RESISTANCE_ZONE, X_PRICE_HIGH, X_PRICE_UP // ); if (!result) { return result; } // result = IsValid(); if (result && range > 0) { // datetime time = bar.time; int periodSeconds = PeriodSeconds(bar.period); // datetime from = !useRangeAsStart ? (datetime)((int)time - (range * periodSeconds)) : time; datetime to = (datetime)((int)time + (range * periodSeconds)); // From(from); To(to); } // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_RESISTANCE_ZONE; // return result; } // protected: // // private: // // }; // // Order Block ... class XCOrderBlock : public XCBarZone { // public: // // // Constructor ... void XCOrderBlock() { } // // Deconstructor ... void ~XCOrderBlock() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool Init( XOHCL &bar, ENUM_X_DIRECTION dir // ) { // bool result = false; // result = bar.IsValid() && (dir == X_DIRECTION_BULLISH || dir == X_DIRECTION_BEARISH); if (!result) { return result; } // ENUM_XPOIS mTT = IsSpecifiedBullish(dir) ? X_POI_BULLISH_ORDERBLOCK : X_POI_BEARISH_ORDERBLOCK; // result = InitBarZone( bar, mTT, X_PRICE_HIGH, X_PRICE_LOW // ); if (!result) { return result; } // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Check is Bullish ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = IsValid() && Type() == X_POI_BULLISH_ORDERBLOCK; // return result; } /** * Check is Bearish ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = IsValid() && Type() == X_POI_BEARISH_ORDERBLOCK; // return result; } ENUM_X_DIRECTION GetDirection() { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // if (!IsValid()) { return result; } // result = IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && (mType == X_POI_BULLISH_ORDERBLOCK || mType == X_POI_BEARISH_ORDERBLOCK); // return result; } // protected: // // private: // // }; // // Rejection Bar ... class XCRejectionBar : public XCBarZone { // public: // // // Constructor ... void XCRejectionBar() { } // // Deconstructor ... void ~XCRejectionBar() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool Init( XOHCL &bar // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // bool isBullish = bar.GetLowShadow() > bar.GetHighShadow(); bool isBearish = bar.GetHighShadow() > bar.GetLowShadow(); result = isBullish || isBearish; if (!result) { return result; } // ENUM_X_PRICE upPrice = isBullish ? X_PRICE_HIGH : X_PRICE_DOWN; // ENUM_X_PRICE loPrice = isBullish ? X_PRICE_UP : X_PRICE_LOW; // result = InitBarZone( bar, X_POI_REJECTION_BAR, upPrice, loPrice // ); if (!result) { return result; } // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Check is Bullish ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = IsValid() && Type() == X_POI_REJECTION_BAR && mBar.GetLowShadow() > mBar.GetHighShadow(); // return result; } /** * Check is Bearish ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = IsValid() && Type() == X_POI_REJECTION_BAR && mBar.GetHighShadow() > mBar.GetLowShadow(); // return result; } // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_REJECTION_BAR; // return result; } // protected: // // private: // // }; // // Momentum Bar ... class XCMomentumBar : public XCBarZone { // public: // // // Constructor ... void XCMomentumBar() { } // // Deconstructor ... void ~XCMomentumBar() { } // // Tools ... /** * Initialize POI ... * * @param bar: XOHCL instance ... * * @return ( bool ) */ bool Init( XOHCL &bar // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // bool isBullish = bar.IsBullish(); bool isBearish = bar.IsBearish(); result = isBullish || isBearish; if (!result) { return result; } // result = InitBarZone( bar, X_POI_MOMENTUM_BAR, X_PRICE_HIGH, X_PRICE_LOW // ); if (!result) { return result; } // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Check is Bullish ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = IsValid() && mBar.IsBullish() && Type() == X_POI_MOMENTUM_BAR; // return result; } /** * Check is Bearish ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = IsValid() && mBar.IsBearish() && Type() == X_POI_MOMENTUM_BAR; // return result; } // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidBarZone() && mType == X_POI_MOMENTUM_BAR; // return result; } // protected: // // private: // // }; // // Fair Value Gap ... class XCFVG : public XCTwoBarZone { // public: // // // Constructor ... void XCFVG() { } // // Deconstructor ... void ~XCFVG() { } // // Tools ... /** * Initialize POI ... * * @param startBar: XOHCL instance ... * @param endBar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool Init( XOHCL &startBar, XOHCL &endBar, ENUM_X_DIRECTION dir // ) { // bool result = false; // result = endBar.IsValid() && startBar.IsValid() && (dir == X_DIRECTION_BULLISH || dir == X_DIRECTION_BEARISH); if (!result) { return result; } // bool isDirBullish = IsSpecifiedBullish(dir); ENUM_XPOIS mTT = isDirBullish ? X_POI_BULLISH_FVG : X_POI_BEARISH_FVG; // bool useFistForUpper = isDirBullish ? false : true; ENUM_X_PRICE upPrice = isDirBullish ? X_PRICE_LOW : X_PRICE_HIGH; ENUM_X_PRICE loPrice = isDirBullish ? X_PRICE_HIGH : X_PRICE_LOW; // result = InitTwoBarZone( startBar, endBar, mTT, useFistForUpper, upPrice, loPrice // ); if (!result) { return result; } // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... /** * Check is Bullish ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = IsValid() && Type() == X_POI_BULLISH_FVG; // return result; } /** * Check is Bearish ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = IsValid() && Type() == X_POI_BEARISH_FVG; // return result; } ENUM_X_DIRECTION GetDirection() { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // if (!IsValid()) { return result; } // result = IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidTwoBarZone() && (mType == X_POI_BULLISH_FVG || mType == X_POI_BEARISH_FVG); // return result; } // protected: // // private: // // }; // // Ticks Zones ... // class XCTickZone : public CObject { // // Public ... public: // // Props ... string symbol; ENUM_TIMEFRAMES period; // double high; double low; int ticks; double percent; // ulong volume; double volumePercent; // // Compare Two Zone With Each Other ... virtual int Compare( const CObject *node, const int mode = 0 // ) const { // const XCTickZone *other = (XCTickZone *)node; // return other.ticks - ticks; } // bool IsValid() { // bool result = false; // result = high > 0 && low > 0 && high > low && ticks > 0 && percent > 0; // return result; } // // Protected ... protected: // // Private ... private: // }; // class XCTicksZone : public XCTwoBarZone { // public: // // // Constructor ... void XCTicksZone() { Default(); } // // Deconstructor ... void ~XCTicksZone() { } // // Getter(s) / Setter(s) ... /** * Get Number of Ticks Levels ... * * @return ( int ) */ int Levels() { return mLevels; } /** * Set Number of Ticks Levels ... * * @return ( int ) */ void Levels(int value) { // if (value < 2) { value = 2; } // mLevels = value; } /** * Apply Default Config ... */ virtual void Default() { // Levels(10); } // // Tools ... /** * Initialize POI ... * * @param startBar: XOHCL instance ... * @param endBar: XOHCL instance ... * * @return ( bool ) */ bool Init( XOHCL &startBar, XOHCL &endBar, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // result = endBar.IsValid() && startBar.IsValid(); if (!result) { return result; } // if (!IsSpecifiedValid(forPeriod)) { forPeriod = endBar.period; } // // Calculate Start and End Time ... datetime from = startBar.time; datetime to = endBar.time; ulong fromM = ((ulong)startBar.time * 1000); ulong toM = ((ulong)endBar.time * 1000); // // Symbol and Period ... string symbol = startBar.symbol; ENUM_TIMEFRAMES period = startBar.period; // // Prepare Zones Array ... mZones.Clear(); // // Retrieve Ticks between Times ... SpecificClean(mTicks); CopyTicksRange( symbol, mTicks, COPY_TICKS_ALL, fromM, toM // ); // // Ticks Volumes ... int ticksVolumeCount = CopyTickVolume( symbol, forPeriod, from, to, mTickVolumes // ); if (IsValidSize(ticksVolumeCount)) { // mVolumes = 0; for (int i = 0; i < ticksVolumeCount; i++) { mVolumes += mTickVolumes[i]; } } // // Retrieve Highs ... SpecificClean(mHighs); CopyHigh( symbol, period, from, to, mHighs // ); // // Retrieve Lows ... SpecificClean(mLows); CopyLow( symbol, period, from, to, mLows // ); // // Find Highest Value in Range ... int highIDX = ArrayMaximum(mHighs); mRangeHigh = mHighs[highIDX]; // // Find Lowest Value in Range ... int lowIDX = ArrayMinimum(mLows); mRangeLow = mLows[lowIDX]; // datetime mTimes[]; CopyTime( symbol, period, from, to, mTimes // ); mRangeHighTime = mTimes[highIDX]; mRangeLowTime = mTimes[lowIDX]; // double mRangeSize = mRangeHigh - mRangeLow; // // Create Zones ... for (int i = 0; i < Levels(); i++) { // // Instance a New Zone ... XCTickZone *iZone = new XCTickZone(); // iZone.symbol = symbol; iZone.period = period; // // Calculate Each Zones High / Low based on Range ... double iH = mRangeHigh - mRangeSize * i / Levels(); double iL = mRangeHigh - mRangeSize * (i + 1) / Levels(); // // Set Zone High Low Properties ... iZone.low = iL; iZone.high = iH; // // Add Zone to Zone Array Objects ... mZones.Add(iZone); } // // Calculate Each Zone Ticks ... int ticksCount = ArraySize(mTicks); for (int i = 0; i < ticksCount; i++) { // // Retrieve Tick ... MqlTick iTick = mTicks[i]; // // Loop through Zones ... for (int j = 0; j < Levels(); j++) { // // Rejrieve j indexed Zone Object ... XCTickZone *jZone = mZones.At(j); // bool isInRange = IsTickInZoneRange( iTick, jZone // ); if (isInRange) { // jZone.ticks++; break; } } } // // Calculating Zone Percents ... for (int i = 0; i < Levels(); i++) { // XCTickZone *iZone = mZones.At(i); // double percent = CalculateZoneTickPercent(iZone); iZone.percent = percent; } // // Sort Zones Based on Percents ... mZones.Sort(); // mUpper = mRangeHigh; mLower = mRangeLow; mType = X_POI_TICKS_ZONES; mEndBar = endBar; mStartBar = startBar; From(startBar.time); To(endBar.time); // result = IsValid(); if (!result) { return result; } // // Try to Find Out PERIOD_1M times in each zone ... datetime to1M = (datetime)((int)endBar.time + PeriodSeconds(period) - 60); int to1MIndex = iBarShift( symbol, forPeriod, to1M // ); int from1MIndex = iBarShift( symbol, forPeriod, from // ); for (int i = from1MIndex; i > to1MIndex; i--) { // XOHCL iBar; bool isInited = iBar.Init( symbol, forPeriod, i // ); if (!isInited) { continue; } ulong iVolume = iTickVolume( symbol, forPeriod, i // ); // // Loop through Zones ... for (int j = 0; j < Levels(); j++) { // XCTickZone *jZone = mZones.At(j); if (!jZone.IsValid()) { continue; } // // Check iBar is Inside jZone ... bool isIBarInside = iBar.GetUp() < jZone.high && iBar.GetDown() > jZone.low; // iBar.low < jZone.high || // iBar.high > jZone.low; if (isIBarInside) { jZone.volume += iVolume; } } } // // Calculate Volume Percent ... for (int i = 0; i < Levels(); i++) { // XCTickZone *iZone = mZones.At(i); // if (mVolumes > 0) { iZone.volumePercent = (double)(iZone.volume * 100 / mVolumes); } } // return result; } // // Getter(s) / Setter(s) ... /** * Retrieve Zones Count ... * * @return ( int ) */ int Count() { return mZones.Total(); } /** * Retrieve Specified Sorted Zones ... * * @param index: Integer ... * * @return ( XCTickZone * ) */ XCTickZone *GetZone(int index) { // if (!IsValidIndex(index)) { return NULL; } // return mZones.At(index); } /** * Calculate Liquidity Percent for Specified Direction ... * * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... * @param price: Double, Specified Price ... * * @return ( double ) */ double CalculateLiquidityPercent( ENUM_X_DIRECTION forDirection, double price // ) { // double result = 0; // int count = Count(); if (price <= 0 || !IsValid() || !IsValidSize(count) || forDirection == X_DIRECTION_ALL || forDirection == X_DIRECTION_NONE) { return result; } // bool isBullish = forDirection == X_DIRECTION_BULLISH; // for (int i = 0; i < count; i++) { // XCTickZone *iZone = GetZone(i); // if (iZone.IsValid()) { // result += !isBullish && price > iZone.high ? iZone.percent : isBullish && price < iZone.low ? iZone.percent : 0; } } // return result; } // // Overrides ... bool IsValid() override { // bool result = false; // result = IsValidFrom() && IsValidTwoBarZone() && Levels() > 0 && mZones.Total() == Levels() && mRangeHigh > 0 && mRangeLow > 0; // return result; } // protected: // // private: // // Props ... // MqlTick mTicks[]; double mHighs[]; double mLows[]; ulong mVolumes; ulong mTickVolumes[]; double mRangeHigh; datetime mRangeHighTime; double mRangeLow; datetime mRangeLowTime; // int mLevels; // Number of Ticks Levels ... // CArrayObj mZones; /** * Check a Tick is in a Zone rage or not ... * * @param tick: MqlTick instance ... * @param zone: XCTickZone instance ... * * @return ( bool ) */ bool IsTickInZoneRange( MqlTick &tick, XCTickZone *zone // ) { // bool result = false; // result = // tick.bid >= zone.low && tick.bid <= zone.high // ; // return result; } /** * Calculate Zone Tick Percent ... * * @param zone: XCTickZone instance ... * @param normalizationDigits: Integer ... * * @return ( double ) */ double CalculateZoneTickPercent( XCTickZone *zone, int normalizationDigits = 2 // ) { // double result = 0; // if (normalizationDigits < 2 || normalizationDigits > 5) { normalizationDigits = 2; } // int ticksCount = ArraySize(mTicks); if (ticksCount <= 0) { return result; } // result = (double)zone.ticks / ticksCount * 100; result = NormalizeDouble(result, normalizationDigits); // return result; } // }; // // Trading Day ... class XCDay : public XCFromToZone { // public: // // // Constructor ... void XCDay() { } // // Deconstructor ... void ~XCDay() { } // // Tools ... /** * Initialize POI ... * * @return ( bool ) */ bool Init() { // bool result = false; // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... // protected: // // private: // // }; // // Trading Session ... class XCSession : public XCFromToZone { // public: // // // Constructor ... void XCSession() { } // // Deconstructor ... void ~XCSession() { } // // Tools ... /** * Initialize POI ... * * @return ( bool ) */ bool Init() { // bool result = false; // result = IsValid(); // return result; } // // Getter(s) / Setter(s) ... // // Overrides ... // protected: // // private: // // }; // struct XBoxZone { // // Props ... string symbol; ENUM_TIMEFRAMES period; // double upper; double lower; // datetime from; datetime to; // string type; ENUM_X_DIRECTION dir; // // Constructor ... XBoxZone() { Clean(); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // upper = 0; lower = 0; to = NULL; from = NULL; symbol = NULL; period = NULL; dir = X_DIRECTION_NONE; // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // upper > 0 && lower > 0 && from < to && IsValid(to) && upper >= lower && IsValid(from) && IsValid(symbol) && IsValid(period) // ; // return result; } bool IsBullish() { return IsValid() && IsBullish(dir); } bool IsBearish() { return IsValid() && IsBearish(dir); } bool IsSameAs(XBoxZone &item) { // return IsValid() && dir == item.dir && from == item.from && type == item.type && lower == item.lower && upper == item.upper && symbol == item.symbol && period == item.period; } /** * Check Box is Same as another ... * * @param box: XBoxZone instance Reference ... * * @return ( bool ) */ bool IsSame(XBoxZone &box) { // bool result = false; // result = IsValid() && box.IsValid(); if (!result) { return result; } // result = // dir == box.dir && from == box.from && type == box.type && upper == box.upper && lower == box.lower && symbol == box.symbol && period == box.period // ; // return result; } /** * Retrieve Unique Identifier ... * * @return ( string ) */ string GetTag() { // string result = // "XBOX" + "_" + ToString(dir) + "_" + symbol + "_" + ToString(period) + "_" + ToString(upper) + "_" + ToString(lower) // ; // return result; } }; //