// // 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, // X_BULLISH_SHARP, X_BEARISH_SHARP, // X_BULLISH_SPIKE, X_BEARISH_SPIKE, // X_BULLISH_PULLBACK, X_BEARISH_PULLBACK, }; // // 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, X_BULLISH_SHARP_DETECTED, X_BEARISH_SHARP_DETECTED, X_BULLISH_SPIKE_DETECTED, X_BEARISH_SPIKE_DETECTED, X_BULLISH_PULLBACK_DETECTED, X_BEARISH_PULLBACK_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; // case X_BULLISH_SPIKE: result = "XBULLSPK"; break; // case X_BEARISH_SPIKE: result = "XBEARSPK"; 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, ENUM_X_PRICE startPrice, ENUM_X_PRICE endPrice // ) { // 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; // int startIndex = startBar.Index(); int endIndex = endBar.Index(); // double mStartPrice = startBar.GetPrice(startPrice); double mEndPrice = endBar.GetPrice(endPrice); bool isStartOverEnd = mStartPrice > mEndPrice; // if (isStartOverEnd) { // mUpperPrice = startPrice; mLowerPrice = endPrice; } else { // mUpperPrice = endPrice; mLowerPrice = startPrice; } // mUpper = MathMax(mStartPrice, mEndPrice); mLower = MathMin(mStartPrice, mEndPrice); // 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; // ENUM_X_PRICE startPrice = isDirBullish ? X_PRICE_HIGH : X_PRICE_LOW; ENUM_X_PRICE endPrice = isDirBullish ? X_PRICE_LOW : X_PRICE_HIGH; // result = InitTwoBarZone( startBar, endBar, mTT, startPrice, endPrice // ); 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)to * 1000); ulong toM = ((ulong)from * 1000); // // Symbol and Period ... string symbol = startBar.symbol; ENUM_TIMEFRAMES period = startBar.period; // // Prepare Zones Array ... mZones.Clear(); // // Retrieve Ticks between Times ... SpecificClean(mTicks); int res = 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(endBar.time); To(startBar.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; } // bool GetMaxTickZone(XCTickZone *&zone) { // bool result = false; // zone = NULL; // result = IsValid(); if (!result) { return result; } // int count = Count(); for (int i = 0; i < count; i++) { // XCTickZone *iZone = GetZone(i); // bool canSet = zone == NULL ? true : zone.ticks < iZone.ticks ? true : false; if (canSet) { zone = iZone; } // ZeroMemory(iZone); } // result = zone != NULL && zone.IsValid(); // return result; } // bool GetMinTickZone(XCTickZone *&zone) { // bool result = false; // zone = NULL; // result = IsValid(); if (!result) { return result; } // int count = Count(); for (int i = 0; i < count; i++) { // XCTickZone *iZone = GetZone(i); // bool canSet = zone == NULL ? true : zone.ticks > iZone.ticks ? true : false; if (canSet) { zone = iZone; } // ZeroMemory(iZone); } // result = zone != NULL && zone.IsValid(); // return result; } // bool GetMaxVolumeZone(XCTickZone *&zone) { // bool result = false; // zone = NULL; // result = IsValid(); if (!result) { return result; } // int count = Count(); for (int i = 0; i < count; i++) { // XCTickZone *iZone = GetZone(i); // bool canSet = zone == NULL ? true : zone.volume < iZone.volume ? true : false; if (canSet) { zone = iZone; } // ZeroMemory(iZone); } // result = zone != NULL && zone.IsValid(); // return result; } // bool GetMinVolumeZone(XCTickZone *&zone) { // bool result = false; // zone = NULL; // result = IsValid(); if (!result) { return result; } // int count = Count(); for (int i = 0; i < count; i++) { // XCTickZone *iZone = GetZone(i); // bool canSet = zone == NULL ? true : zone.volume > iZone.volume ? true : false; if (canSet) { zone = iZone; } // ZeroMemory(iZone); } // result = zone != NULL && zone.IsValid(); // 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: // // }; // template bool ToBox( T *&source[], XBoxZone &dest[] // ) { // bool result = false; // Clean(dest); // int count = ArraySize(source); result = IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // T *item = source[i]; // if (item != NULL) { // XBoxZone iBox; bool hasBox = ToBox( iBox, item // ); // if (hasBox) { // AddRef( iBox, dest // ); } } } // int destCount = ArraySize(dest); result = IsValidSize(destCount); // return result; } template int GetOldest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetOldest(boxes); // Clean(boxes); // return result; } template int GetYoungest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetYoungest(boxes); // Clean(boxes); // return result; } template int GetLowest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetLowest(boxes); // Clean(boxes); // return result; } template int GetHighest( T *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone boxes[]; bool isConverted = ToBox( source, boxes // ); if (!isConverted) { return result; } // int boxesCount = ArraySize(boxes); // if (count != boxesCount) { return result; } // result = GetHighest(boxes); // Clean(boxes); // return result; } template bool IsSame( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = sourceBox.IsSameAs(destBox); // return result; } template bool IsBelow( T *source, T *dest, bool ignoreInside = false // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxBelow( sourceBox, destBox, ignoreInside // ); // return result; } template bool IsAbove( T *source, T *dest, bool ignoreInside = false // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxAbove( sourceBox, destBox, ignoreInside // ); // return result; } template bool IsInside( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxInside( sourceBox, destBox // ); // return result; } template bool IsInsideOr( T *source, T *dest // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // XBoxZone destBox; result = ToBox( destBox, dest // ); if (!result) { return result; } // result = IsBoxInsideOr( sourceBox, destBox // ); // return result; } template bool FindIndex( int &index, T *item, T *&items[] // ) { // bool result = false; // index = -1; // XBoxZone itemBox; result = ToBox( itemBox, item // ); if (!result) { return result; } // XBoxZone itemsBox[]; result = ToBox( items, itemsBox // ); if (!result) { return result; } // result = FindBoxIndex( index, itemBox, itemsBox // ); // return result; } template bool IsInside( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsInsideBox( value, sourceBox // ); // return result; } template bool IsAbove( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsAboveBox( value, sourceBox // ); // return result; } template bool IsBelow( double value, T *source // ) { // bool result = false; // XBoxZone sourceBox; result = ToBox( sourceBox, source // ); if (!result) { return result; } // result = IsBelowBox( value, sourceBox // ); // return result; } // // // // template void SortZones( T *&source[], ENUM_X_DIRECTION forDir, bool ignoreInside = true // ) { // int idx = -1; int count = 0; bool has = false; // has = HasDirection(forDir); if (!has) { return; } // bool isBullish = IsBullish(forDir); // count = ArraySize(source); has = IsValidSize(count); if (!has) { return; } // T *tmpItems[]; T *last = NULL; bool hasLast = false; while (HasChild(source)) { // if (!hasLast) { // idx = GetOldest(source); hasLast = IsValidIndex(idx); if (hasLast) { // last = source[idx]; ArrayRemove( source, idx, 1 // ); // Add( last, tmpItems // ); } // count = ArraySize(source); has = IsValidSize(count); if (!has) { // ZeroMemory(last); break; } } if (!hasLast) { // ZeroMemory(last); break; } // T *item = NULL; idx = GetOldest(source); has = IsValidIndex(idx); if (!has) { // ZeroMemory(last); ZeroMemory(item); break; } item = source[idx]; ArrayRemove( source, idx, 1 // ); // bool isAbove = IsAbove( item, last, ignoreInside // ); // bool isBelow = IsBelow( item, last, ignoreInside // ); // has = isBullish ? isAbove : isBelow; if (has) { // Add( item, tmpItems // ); // last = item; hasLast = item != NULL; } } // Clean(source); Copy( tmpItems, source // ); // Clean(tmpItems); } /** * Extract all Zones Which provided bar is Inside it ... * * @return ( int ) */ template int ExtractInsideZones( XOHCL &bar, // Bar ... T *&zones[], // Source of Zones ... T *&dest[] // Dest (all inside Zones) ... ) { // int result = 0; // Clean(dest); // int count = ArraySize(zones); bool isValid = bar.IsValid() && IsValidSize(count); if (!isValid) { return result; } // for (int i = 0; i < count; i++) { // T *iZone = zones[i]; // bool isHighInside = IsInside( bar.high, iZone // ); // bool isLowInside = IsInside( bar.low, iZone // ); // bool isInside = isLowInside && isHighInside; // if (isInside) { // Add( iZone, dest // ); } // ZeroMemory(iZone); } // result = ArraySize(dest); // return result; } /** * Add Specific Item into a Collection Reference only if it's not Exists ... * * @return ( bool ) */ template bool AddIfNotExists( T *item, T *&items[] // ) { // bool result = false; // result = item != NULL; if (!result) { return result; } // int before = ArraySize(items); // int idx = FindIndex( item, items // ); bool has = IsValidIndex(idx); result = !has; if (!result) { return result; } // Add( item, items // ); // int after = ArraySize(items); // result = after > before; // return result; } /** * Add items Collection reference Members into source Collection only if it's not Exists ...alignas * @return ( int ) */ template int AddIfNotExists( T *&items[], T *&sources[] // ) { // int result = 0; // bool has = HasChild(items); if (!has) { return result; } // int before = ArraySize(sources); // int count = ArraySize(items); for (int i = 0; i < count; i++) { // has = AddIfNotExists( items[i], sources // ); } // int after = ArraySize(sources); // result = after > before; // return result; } /** * Update to Time of Specifiex Collection ... * * @param items: XOBFVG instance Collection ... * @param value: datetime ... */ template void SpecifiedUpdateTo( T *&items[], datetime value = NULL // ) { // value = NormalizeTime(value); // int count = ArraySize(items); bool has = HasChild(items); if (!has) { return; } // for (int i = 0; i < count; i++) { items[i].To(value); } } /** * Check a Box is Used or not ... * * @param box: XBoxZone instance Reference ... * @param fromIndex: int ... * @param toIndex: int * @param forPeriod: Specified Period ... * * @return ( bool ) */ bool IsBoxUsed( XBoxZone &box, int fromIndex, int toIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (toIndex < 0) { toIndex = 0; } // result = // box.IsValid() && fromIndex > 0 && fromIndex > toIndex // ; if (!result) { return result; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // ENUM_X_DIRECTION forDir = box.dir; bool isBullish = IsBullish(forDir); // bool isTouched = false; for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; bool isInited = iBar.Init( box.symbol, forPeriod, i // ); // isTouched = isInited && (isBullish ? iBar.low > box.upper : iBar.high < box.lower); if (!isTouched) { continue; } // iBar.Clean(); break; } // result = isTouched; // return result; } /** * Validate Box ... * * @param box: XBoxZone instance ... * @param barIndex: int, Current Bar Index ... * @param forPeriod: Testing Period ... * * @return ( bool ) */ bool IsBoxValid( XBoxZone &box, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // int toIndex = iBarShift( box.symbol, forPeriod, box.to // ); result = IsValidIndex(toIndex); if (!result) { return result; } // XOHCL iBar; bool isBullish = box.IsBullish(); for (int i = barIndex; i < toIndex; i++) { // result = iBar.Init( box.symbol, forPeriod, i // ); if (!result) { break; } // result = isBullish ? iBar.low > box.upper : iBar.high < box.lower; if (!result) { break; } // iBar.Clean(); } // iBar.Clean(); // return result; } /** * Check Box Breaked ... * * @param box: XBoxZone instance ... * @param barIndex: int, Current Bar Index ... * @param forPeriod: Testing Period ... * * @return ( bool ) */ bool IsBoxBreaked( XBoxZone &box, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // int toIndex = iBarShift( box.symbol, forPeriod, box.to // ); result = IsValidIndex(toIndex); if (!result) { return result; } // XOHCL iBar; bool isBullish = box.IsBullish(); for (int i = barIndex; i < toIndex; i++) { // result = iBar.Init( box.symbol, forPeriod, i // ); if (!result) { break; } // result = isBullish ? iBar.high < box.lower : iBar.low > box.upper; if (!result) { break; } // iBar.Clean(); } // iBar.Clean(); // return result; } /** * Check a Box is Breaked or not ... * * @param box: XBoxZone instance Reference ... * @param fromIndex: int ... * @param toIndex: int * @param forPeriod: Specified Period ... * * @return ( bool ) */ bool IsBoxBreaked( XBoxZone &box, int fromIndex, int toIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (toIndex < 0) { toIndex = 0; } // result = // box.IsValid() && fromIndex > 0 && fromIndex > toIndex // ; if (!result) { return result; } // if (!IsValid(forPeriod)) { forPeriod = box.period; } // ENUM_X_DIRECTION forDir = box.dir; bool isBullish = IsBullish(forDir); // bool isBreaked = false; for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; bool isInited = iBar.Init( box.symbol, forPeriod, i // ); // isBreaked = isInited && (isBullish ? iBar.high <= box.lower : iBar.low >= box.upper); if (!isBreaked) { continue; } // iBar.Clean(); break; } // result = isBreaked; // return result; } /** * 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; } /** * Check Source Box is Below Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param ignoreInside: bool ... * * @return ( bool ) */ bool IsBoxBelow( XBoxZone &source, XBoxZone &dest, bool ignoreInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // if (!ignoreInside) { result = source.upper < dest.lower; } else { result = (source.upper < dest.lower || source.upper >= dest.upper) && source.lower < dest.lower; } // return result; } /** * Check Source Box is Above Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param ignoreInside: bool ... * * @return ( bool ) */ bool IsBoxAbove( XBoxZone &source, XBoxZone &dest, bool ignoreInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // if (!ignoreInside) { result = source.lower > dest.upper; } else { result = (source.lower > dest.upper || source.lower <= dest.upper) && source.upper > dest.upper; } // return result; } /** * Check Source Box is Inside Dest ... * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param forceSideOut: bool, force check Box has One Side Out ... * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... * * @return ( bool ) */ bool IsBoxInside( XBoxZone &source, XBoxZone &dest, bool forceSideOut = false, // bool ignoreSideOut = true // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // bool isBullish = IsBullish(dest.dir); // if (!forceSideOut) { // if (ignoreSideOut) { // result = source.lower >= dest.lower && source.upper <= dest.upper; } else { result = source.lower >= dest.lower || source.upper <= dest.upper; } } else { // bool hasSideIn = isBullish ? source.lower >= dest.lower : source.upper <= dest.upper; bool hasSideOut = isBullish ? source.upper >= dest.upper : source.lower <= dest.lower; result = hasSideIn && hasSideOut; } // return result; } /** * Detect source BoX is Inside Dest Box or Have a Side Out on it ... * * @param source: XBoxZone instance, source box which checks by dest ... * @param dest: XBoxZone instance, dest Box which compares source with it ... * * @return ( bool ) */ bool IsBoxInsideOr( XBoxZone &source, XBoxZone &dest, bool forceInside = false // ) { // bool result = false; // result = source.IsValid() && dest.IsValid() && !source.IsSameAs(dest); if (!result) { return result; } // bool isInside = source.upper <= dest.upper && source.upper >= dest.lower && source.lower >= dest.lower && source.lower <= dest.upper; bool isUpperInside = source.upper <= dest.upper && source.upper >= dest.lower; bool isLowerInside = source.lower >= dest.lower && source.lower <= dest.upper; // result = forceInside ? isInside : (isInside || isLowerInside || isUpperInside); // return result; } /** * Check Value is Inside Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsInsideBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value <= box.upper && value >= box.lower; // return result; } /** * Check Bar is Inside Specified Box ... * * @param bar: XOHCL instance reference, Specified Bar ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsInsideBox( XOHCL &bar, XBoxZone &box // ) { // bool result = false; // // Validate Args ... result = bar.IsValid() && box.IsValid(); if (!result) { return result; } // result = bar.close <= box.upper && bar.close >= box.lower; // return result; } /** * Check Value is Above Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsAboveBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value > box.upper; // return result; } /** * Check Value is Below Specified Box ... * * @param value: double ... * @param box: XCBozZone instance Reference ... * * @return ( bool ) */ bool IsBelowBox( double value, XBoxZone &box // ) { // bool result = false; // result = value > 0 && box.IsValid() && value < box.lower; // return result; } /** * Find an Inside Box of source in a Collection ... * * @param index: int, Founded Index ... * @param source: XBoxZone instance ... * @param dest: XBoxZone instance Collection ... * * @return ( bool ) */ bool HasInsideBox( int &index, XBoxZone &source, XBoxZone &dest[] // ) { // bool result = false; // index = -1; // result = source.IsValid() && HasChild(dest); // int count = ArraySize(dest); for (int i = 0; i < count; i++) { // XBoxZone iBox = dest[i]; // bool isInside = !iBox.IsSameAs(source) && IsBoxInsideOr( iBox, source // ); if (isInside) { // index = i; iBox.Clean(); // break; } // iBox.Clean(); } // result = IsValidIndex(index); // return result; } ///////////////////////////////////////////// // // Analyse Bar Patterns ... if (result && config.analyseBarPatterns) { // // Try to Detect Bars Analysis ... int fromIndex = -1; if (!IsXValid(fromTime)) { fromIndex = barIndex + config.loopback; } else { fromIndex = GetBarIndex( symbol, period, fromTime // ); } result = IsValidIndex(fromIndex); if (result) { // fromIndex = MathMin(fromIndex, barIndex + config.requiredPivots); // for (int i = barIndex; i < fromIndex; i++) { // tmpBar.Clean(); tmpBarAnalysis.Clean(); result = structure.bar.BarAt(i, tmpBar); result = result && AnalyseBarPatterns( tmpBar, tmpBarAnalysis, config.barsAnalysisConfig // ); if (!result) { break; } // AddRef( tmpBarAnalysis, structure.barsAnalysis // ); } } } //////////////////////////////////////////////// /** * Draw Specified Market Structure Based on Given Configs ... * * @param structure: XFIMAMarketStructure, reference to Provide Specifid Market Structure ... * @param config: XFIMAMarketStructureDrawerConfig, reference to Provide Drawing Configurations ... */ void DrawMarketStructure( XFIMAMarketStructure &structure, XFIMAMarketStructureDrawerConfig &config // ) { // // Validate ... bool has = structure.IsValid(); if (!has) { return; } // // PV Analysis ... if (config.drawPVAnalysis) { // has = structure.pvAnalysis.IsValid(); if (has) { // DrawPivotAnalysis( structure.pvAnalysis, config.pivotAnalysisDrawConfig // ); } } // // ZG Analysis ... if (config.drawZGAnalysis) { // has = structure.zgAnalysis.IsValid(); if (has) { // DrawPivotAnalysis( structure.zgAnalysis, config.pivotAnalysisDrawConfig // ); } } // // Bars Analysis ... if (config.drawBarsAnalysis) { // int count = ArraySize(structure.barsAnalysis); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { // DrawPatternAnalysis( structure.barsAnalysis[i], config.barAnalysisDrawConfig // ); } } } }