// struct XOBFVGPivot { // // Props ... double value; datetime at; // // Constructor ... XOBFVGPivot() { Clean(); } // // Tools ... // void Clean() { // value = 0; at = NULL; // ZeroMemory(this); } // bool IsValid() { // bool result = false; // result = value > 0 && IsValid(at); // return result; } }; // struct XOBFVG { // // Props ... XCFVG *fvgs[]; XCOrderBlock *ob; // // Constructor ... XOBFVG() { Clean(); } // // Tools ... // void Clean() { // Clean(fvgs); ZeroMemory(ob); // ZeroMemory(this); } // bool IsValid() { // bool result = false; // result = HasOB() && HasFVGs(); if (!result) { return result; } // XOHCL passedBar; bool isBodyOut; bool isOBStarted = ob.IsStarted( ob.GetDirection(), passedBar, isBodyOut // ); // int idx = GetOldest(fvgs); result = IsValidIndex(idx); if (!result) { // passedBar.Clean(); return result; } // bool isFVGStarted = fvgs[idx].IsStarted( ob.GetDirection(), passedBar, isBodyOut // ); // result = isOBStarted && isFVGStarted; // passedBar.Clean(); // return result; } // bool HasOB() { return ob != NULL && ob.IsValid(); } // bool HasFVGs() { return HasChild(fvgs); } // int CountFVGs() { return ArraySize(fvgs); } // ENUM_X_DIRECTION GetDirection() { // ENUM_X_DIRECTION result = X_DIRECTION_NONE; // bool isValid = IsValid(); if (!isValid) { return result; } // result = ob.GetDirection(); // return result; } // bool IsBullish() { return IsBullish(GetDirection()); } // bool IsBearish() { return IsBearish(GetDirection()); } // int GetSwings( XOBFVGPivot &pivots[] // ) { // int result = 0; // Clean(pivots); // if (!IsValid()) { return result; } // ENUM_X_DIRECTION forDir = GetDirection(); bool isBullish = IsBullish(forDir); // XOHCL passedBar; XOBFVGPivot iPivot; bool isPassed = false; double appliedPrice = 0; bool isBodyState = false; // // Start ... isPassed = ob.IsStarted( forDir, passedBar, isBodyState // ); if (isPassed) { // appliedPrice = isBullish ? passedBar.low : passedBar.high; // iPivot.Clean(); iPivot.value = appliedPrice; iPivot.at = passedBar.time; // AddRef( iPivot, pivots // ); // iPivot.Clean(); } // // Activation ... isPassed = ob.IsActivated( forDir, passedBar, isBodyState // ); if (isPassed) { // appliedPrice = isBullish ? passedBar.low : passedBar.high; // iPivot.Clean(); iPivot.value = appliedPrice; iPivot.at = passedBar.time; // AddRef( iPivot, pivots // ); // iPivot.Clean(); } // // Worked ... isPassed = ob.IsWorked( forDir, passedBar, isBodyState // ); if (isPassed) { // appliedPrice = isBullish ? passedBar.low : passedBar.high; // iPivot.Clean(); iPivot.value = appliedPrice; iPivot.at = passedBar.time; // AddRef( iPivot, pivots // ); // iPivot.Clean(); } // passedBar.Clean(); // result = ArraySize(pivots); // return result; } // bool GetMainFVG( XCFVG *&fvg // ) { // bool result = false; // fvg = NULL; // result = IsValid(); if (!result) { return result; } // int idx = GetOldest(fvgs); result = IsValidIndex(idx); if (!result) { // ZeroMemory(fvg); return result; } // fvg = fvgs[idx]; result = fvg != NULL && fvg.IsValid(); // return result; } // bool IsValidZone( int barIndex = 0 // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // result = IsValid(); if (!result) { return result; } // XCFVG *tmpFVGs[]; Copy( fvgs, tmpFVGs // ); int count = CountFVGs(); for (int i = 0; i < count; i++) { // XCFVG *iFVG = tmpFVGs[i]; // XOHCL startedBar; bool isBodyOut = false; result = iFVG.IsStarted( iFVG.GetDirection(), startedBar, isBodyOut // ); if (!result) { // ZeroMemory(iFVG); startedBar.Clean(); ArrayRemove( fvgs, i, 1 // ); // continue; } // XOHCL bar; bool isBullish = iFVG.IsBullish(); datetime fromTime = startedBar.NextAt(); // int fromIndex = iBarShift( iFVG.GetSymbol(), iFVG.GetPeriod(), fromTime // ); result = IsValidIndex(fromIndex); if (!result) { // bar.Clean(); ZeroMemory(iFVG); startedBar.Clean(); ArrayRemove( fvgs, i, 1 // ); // continue; } // bool isInited = false; bool isValidFVG = false; for (int j = barIndex; j < fromIndex; j++) { // isInited = bar.Init( iFVG.GetSymbol(), iFVG.GetPeriod(), j // ); if (!isInited) { // bar.Clean(); continue; } // // bool isBarAbove = // bar.low > iFVG.Upper(); // bool isBarBelow = // bar.high < iFVG.Lower(); // bool isBarAbove = bar.GetDown() > iFVG.Upper(); bool isBarBelow = bar.GetUp() < iFVG.Lower(); // isValidFVG = isBullish ? isBarAbove : isBarBelow; if (!isValidFVG) { // bar.Clean(); // break; } // bar.Clean(); } // if (!isValidFVG) { // ArrayRemove( fvgs, i, 1 // ); } // bar.Clean(); ZeroMemory(iFVG); startedBar.Clean(); } // Clean(tmpFVGs); // result = HasFVGs(); // return result; } // bool ToZone(XBoxZone &box) { // bool result = false; // result = ToZoneBox( box, this // ); // return result; } // void AddFVG(XCFVG *fvg) { // int idx = -1; bool has = false; // has = HasOB() && fvg != NULL && fvg.IsValid() && ob.GetDirection() == fvg.GetDirection(); if (!has) { return; } // idx = FindIndex( fvg, fvgs // ); has = !IsValidIndex(idx); if (!has) { return; } // Add( fvg, fvgs // ); } // bool IsSameAs(XOBFVG &item) { // bool result = false; // result = IsValid() && IsSame(ob, item.ob); // return result; } // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; // has = HasOB(); if (has) { ob.To(value); } // has = HasFVGs(); if (has) { // count = CountFVGs(); for (int i = 0; i < count; i++) { fvgs[i].To(value); } } } }; /** * Update to Time of Specifiex Collection ... * * @param items: XOBFVG instance Collection ... * @param value: datetime ... */ void SpecifiedUpdateTo( XOBFVG &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].UpdateTo(value); } } /** * Extract Box Zone's of Specified OBFVG ... * * @param box: XBoxZone instance, represent result ... * @param obfvg: XOBFVG instance, specified Model ... * * @return ( bool ) */ bool ToZoneBox( XBoxZone &box, XOBFVG &obfvg // ) { // bool result = false; // box.Clean(); // // Check Model Validation ... result = obfvg.IsValid(); if (!result) { return result; } // // Retrieve Model Main Fair Value Gap ... XCFVG *fvg; result = obfvg.GetMainFVG(fvg); if (!result) { // box.Clean(); ZeroMemory(fvg); // return result; } // bool isBullish = fvg.IsBullish(); // // Retrieve Main Fair Value Gap's Started Bar ... XOHCL startedBar; bool isBodyOut = false; bool isStarted = fvg.IsStarted( fvg.GetDirection(), startedBar, isBodyOut // ); result = isStarted; if (!result) { // box.Clean(); ZeroMemory(fvg); startedBar.Clean(); // return result; } // // Converts Main Fair Value Gaps to Box ... result = ToBox( box, fvg // ); if (!result) { // box.Clean(); ZeroMemory(fvg); startedBar.Clean(); // return result; } // // Validate Start Bar ... result = isBullish ? startedBar.high >= fvg.Upper() && startedBar.low < fvg.Upper() : startedBar.low <= fvg.Lower() && startedBar.high > fvg.Lower(); if (!result) { // box.Clean(); ZeroMemory(fvg); startedBar.Clean(); // return result; } // // Update Box using Started Bar ... box.lower = isBullish ? box.lower : startedBar.low; box.upper = isBullish ? startedBar.high : box.upper; // box.from = startedBar.NextAt(); // // Check Box Validation ... result = box.IsValid(); if (!result) { box.Clean(); } // // Cleanup Resources ... ZeroMemory(fvg); startedBar.Clean(); // return result; } /** * Converts to XBoxZone ... * * @return ( bool ) */ bool ToBox( XBoxZone &box, XOBFVG &item // ) { // bool result = false; // result = ToBox( box, item.ob // ); // return result; } /** * Converts to XBoxZone ... * * @return ( bool ) */ int ToBox( XOBFVG &source[], XBoxZone &dest[] // ) { // int result = 0; // Clean(dest); int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XOBFVG iZone = source[i]; // XBoxZone iBox; bool hasBox = ToBox( iBox, iZone // ); // if (hasBox) { // AddRef( iBox, dest // ); } // iBox.Clean(); iZone.Clean(); } // result = ArraySize(dest); // return result; } /** * Get Oldest Index ... * * @param source: XOBFVG instance Reference Collection ... * * @return ( int ) */ int GetOldest( XOBFVG &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone tmpBoxes[]; int boxesCount = ToBox( source, tmpBoxes // ); if (!IsValidSize(boxesCount)) { // Clean(tmpBoxes); return result; } // XBoxZone selected; for (int i = 0; i < boxesCount; i++) { // XBoxZone iBox = tmpBoxes[i]; // bool canSet = !selected.IsValid() ? true : selected.from > iBox.from; if (canSet) { // result = i; selected = iBox; } } // Clean(tmpBoxes); selected.Clean(); // return result; } /** * Get Youngest Index ... * * @param source: XOBFVG instance Reference Collection ... * * @return ( int ) */ int GetYoungest( XOBFVG &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone tmpBoxes[]; int boxesCount = ToBox( source, tmpBoxes // ); if (!IsValidSize(boxesCount)) { // Clean(tmpBoxes); return result; } // XBoxZone selected; for (int i = 0; i < boxesCount; i++) { // XBoxZone iBox = tmpBoxes[i]; // bool canSet = !selected.IsValid() ? true : selected.from < iBox.from; if (canSet) { // result = i; selected = iBox; } } // Clean(tmpBoxes); selected.Clean(); // return result; } /** * Get Highest Index ... * * @param source: XOBFVG instance Reference Collection ... * * @return ( int ) */ int GetHighest( XOBFVG &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone tmpBoxes[]; int boxesCount = ToBox( source, tmpBoxes // ); if (!IsValidSize(boxesCount)) { // Clean(tmpBoxes); return result; } // XBoxZone selected; for (int i = 0; i < boxesCount; i++) { // XBoxZone iBox = tmpBoxes[i]; // bool canSet = !selected.IsValid() ? true : selected.upper < iBox.upper; if (canSet) { // result = i; selected = iBox; } } // Clean(tmpBoxes); selected.Clean(); // return result; } /** * Get Lowest Index ... * * @param source: XOBFVG instance Reference Collection ... * * @return ( int ) */ int GetLowest( XOBFVG &source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XBoxZone tmpBoxes[]; int boxesCount = ToBox( source, tmpBoxes // ); if (!IsValidSize(boxesCount)) { // Clean(tmpBoxes); return result; } // XBoxZone selected; for (int i = 0; i < boxesCount; i++) { // XBoxZone iBox = tmpBoxes[i]; // bool canSet = !selected.IsValid() ? true : selected.lower > iBox.lower; if (canSet) { // result = i; selected = iBox; } } // Clean(tmpBoxes); selected.Clean(); // return result; } bool AddIfNotExists( XOBFVG &item, XOBFVG &items[] // ) { // bool result = false; // result = item.IsValid(); if (!result) { return result; } // int before = ArraySize(items); // int idx = FindIndex( item, items // ); bool has = IsValidIndex(idx); result = !has; if (!result) { return result; } // AddRef( item, items // ); // int after = ArraySize(items); // result = after > before; // return result; } int AddIfNotExists( XOBFVG &items[], XOBFVG &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; } // int DrawOBFVG( // XOBFVG &item, XCBaseObject *&objects[], // bool drawOrderBlock = true, bool drawFairValueGaps = true, bool drawAllFVGs = true, // bool drawOBStartedBar = true, bool drawOBActivatedBar = true, bool drawOBBreakedBar = true, bool drawOBWorkedBar = true, // bool drawFVGStartedBar = true, bool drawFVGActivatedBar = true, bool drawFVGBreakedBar = true, bool drawFVGWorkedBar = true, // // Order Block Specs ... // int widthOBStartedBar = 1, color clrOBStartedBar = clrYellow, ENUM_LINE_STYLE styleOBStartedBar = STYLE_SOLID, // int widthOBActivatedBar = 1, color clrOBActivatedBar = clrLime, ENUM_LINE_STYLE styleOBActivatedBar = STYLE_SOLID, // int widthOBBreakedBar = 1, color clrOBBreakedBar = clrRed, ENUM_LINE_STYLE styleOBBreakedBar = STYLE_SOLID, // int widthOBWorkedBar = 1, color clrOBWorkedBar = clrAqua, ENUM_LINE_STYLE styleOBWorkedBar = STYLE_SOLID, // // Fair Value Gap Specs ... // int widthFVGStartedBar = 1, color clrFVGStartedBar = clrYellow, ENUM_LINE_STYLE styleFVGStartedBar = STYLE_SOLID, // int widthFVGActivatedBar = 1, color clrFVGActivatedBar = clrLime, ENUM_LINE_STYLE styleFVGActivatedBar = STYLE_SOLID, // int widthFVGBreakedBar = 1, color clrFVGBreakedBar = clrRed, ENUM_LINE_STYLE styleFVGBreakedBar = STYLE_SOLID, // int widthFVGWorkedBar = 1, color clrFVGWorkedBar = clrAqua, ENUM_LINE_STYLE styleFVGWorkedBar = STYLE_SOLID // ) { // int result = 0; // Clean(objects); // bool isValid = item.IsValid(); if (!isValid) { return result; } // int count = 0; bool has = false; bool isCreated = false; XCBaseObject *tmpObjects[]; // // Order Block ... has = item.HasOB(); if (has && drawOrderBlock) { // Clean(tmpObjects); count = DrawOrderBlock( item.ob, tmpObjects, drawOBStartedBar, drawOBActivatedBar, drawOBBreakedBar, drawOBWorkedBar, widthOBStartedBar, clrOBStartedBar, styleOBStartedBar, widthOBActivatedBar, clrOBActivatedBar, styleOBActivatedBar, widthOBBreakedBar, clrOBBreakedBar, styleOBBreakedBar, widthOBWorkedBar, clrOBWorkedBar, styleOBWorkedBar // ); has = IsValidSize(count); if (has) { // Copy( tmpObjects, objects, false // ); } } // // Fair Value Gap ... if (!drawAllFVGs) { XCFVG *fvg; has = item.GetMainFVG(fvg); if (has && drawFairValueGaps) { // Clean(tmpObjects); int fvgsCount = DrawFairValueGap( fvg, tmpObjects, drawFVGStartedBar, drawFVGActivatedBar, drawFVGBreakedBar, drawFVGWorkedBar, widthFVGStartedBar, clrFVGStartedBar, styleFVGStartedBar, widthFVGActivatedBar, clrFVGActivatedBar, styleFVGActivatedBar, widthFVGBreakedBar, clrFVGBreakedBar, styleFVGBreakedBar, widthFVGWorkedBar, clrFVGWorkedBar, styleFVGWorkedBar // ); has = IsValidSize(fvgsCount); if (has) { // Copy( tmpObjects, objects, false // ); } } } else { // has = item.HasFVGs(); if (has && drawFairValueGaps) { // count = item.CountFVGs(); for (int i = 0; i < count; i++) { // Clean(tmpObjects); int fvgsCount = DrawFairValueGap( item.fvgs[i], tmpObjects, drawFVGStartedBar, drawFVGActivatedBar, drawFVGBreakedBar, drawFVGWorkedBar, widthFVGStartedBar, clrFVGStartedBar, styleFVGStartedBar, widthFVGActivatedBar, clrFVGActivatedBar, styleFVGActivatedBar, widthFVGBreakedBar, clrFVGBreakedBar, styleFVGBreakedBar, widthFVGWorkedBar, clrFVGWorkedBar, styleFVGWorkedBar // ); has = IsValidSize(fvgsCount); if (has) { // Copy( tmpObjects, objects, false // ); } } } } // Clean(tmpObjects); // result = ArraySize(objects); // return result; }