I reviewed your code and the main issue seems to be how you're accessing the rectangle's price levels.
You're using OBJPROP_PRICE, but for OBJ_RECTANGLE objects you should use OBJPROP_PRICE1 and OBJPROP_PRICE2. Since those calls fail, the code just skips deletion. If you switch to the correct properties, it should start working.
Also, be cautious with how you're naming the rectangles. Using TimeToString(...) can create inconsistent names that are harder to match later. It's safer to use something like IntegerToString((int)time[i]) for a consistent and unique name.
I reviewed your code and the main issue seems to be how you're accessing the rectangle's price levels.
You're using OBJPROP_PRICE, but for OBJ_RECTANGLE objects you should use OBJPROP_PRICE1 and OBJPROP_PRICE2. Since those calls fail, the code just skips deletion. If you switch to the correct properties, it should start working.
Also, be cautious with how you're naming the rectangles. Using TimeToString(...) can create inconsistent names that are harder to match later. It's safer to use something like IntegerToString((int)time[i]) for a consistent and unique name.
Hello Miguel hope you are doing well. I did try to use the OBJPROP_PRICE1 and 2 but it gives errors . can i share the same indicator that has IIFVG arrow whcih still wont delete once invalidated. If they can delete its when i shift to drawing IFVG boxes instead of arrow. Kindly help please will appreciate it so much. The fvg part is very okay drawing hidding and deleting is smooth. Just the issue with IFVG arrows that wont delete.
#property indicator_chart_window #property strict #property indicator_buffers 0 #property indicator_plots 0 input int LookbackBars = 100; input int ATR_Period = 14; input double ATR_Multiplier = 0.35; input color BullishColor = clrGreen; input color BearishColor = clrRed; input color iBullishColor = clrLime; // Color for bullish iFVG arrows input color iBearishColor = clrCrimson; // Color for bearish iFVG arrows input int ArrowCodeBullish = 233; input int ArrowCodeBearish = 234; input int ArrowSize = 1; input int ArrowOffsetPoints = 20; input bool ShowFVGArrows = false; // Toggle to show FVG arrows struct FVG { int type; int startBar; int endBar; double highVal; double lowVal; double atr; }; double CalculateATR(const double &high[], const double &low[], const double &close[], int rates_total, int current) { if (current < ATR_Period) return 0.0; double sumTR = 0.0; for (int i = current - ATR_Period + 1; i <= current; i++) { double tr = MathMax(high[i] - low[i], MathMax(MathAbs(high[i] - close[i-1]), MathAbs(low[i] - close[i-1]))); sumTR += tr; } return sumTR / ATR_Period; } void OnDeinit(const int reason) { int total = ObjectsTotal(0, -1, -1); for (int j = total - 1; j >= 0; j--) { string name = ObjectName(0, j); if (StringFind(name, "BullFVG_") == 0 || StringFind(name, "BearFVG_") == 0 || StringFind(name, "iBullFVG_") == 0 || StringFind(name, "iBearFVG_") == 0) ObjectDelete(0, name); } } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if (rates_total < ATR_Period + 3) return prev_calculated; int start = MathMax(ATR_Period, rates_total - LookbackBars - 3); FVG fvgs[]; int fvgCount = 0; // Detect FVGs for(int i = start; i < rates_total - 3; i++) { double atrValue = CalculateATR(high, low, close, rates_total, i); double atr = atrValue * ATR_Multiplier; // Bullish FVG detection if(low[i+2] > high[i] && ((low[i+2] - high[i])/_Point >= atr/_Point)) { FVG fvg = {1, i, i+2, high[i], low[i+2], atr}; ArrayResize(fvgs, fvgCount+1); fvgs[fvgCount++] = fvg; } // Bearish FVG detection else if(high[i+2] < low[i] && ((low[i] - high[i+2])/_Point >= atr/_Point)) { FVG fvg = {-1, i, i+2, high[i+2], low[i], atr}; ArrayResize(fvgs, fvgCount+1); fvgs[fvgCount++] = fvg; } } // Remove existing FVG arrows int total = ObjectsTotal(0, -1, -1); for (int j = total - 1; j >= 0; j--) { string name = ObjectName(0, j); if (StringFind(name, "BullFVG_") == 0 || StringFind(name, "BearFVG_") == 0) ObjectDelete(0, name); } // Draw current valid FVGs if (ShowFVGArrows) { for (int m = 0; m < fvgCount; m++) { FVG fvg = fvgs[m]; bool broken = false; for (int i = fvg.endBar + 1; i < rates_total - 1; i++) { if ((fvg.type == 1 && close[i] < fvg.lowVal) || (fvg.type == -1 && close[i] > fvg.highVal)) { broken = true; break; } } if (broken) continue; string name = (fvg.type == 1 ? "BullFVG_" : "BearFVG_") + IntegerToString(fvg.startBar); double price = (fvg.type == 1) ? (fvg.lowVal - ArrowOffsetPoints * _Point) : (fvg.highVal + ArrowOffsetPoints * _Point); if (ObjectCreate(0, name, OBJ_ARROW, 0, time[fvg.endBar], price)) { ObjectSetInteger(0, name, OBJPROP_ARROWCODE, fvg.type == 1 ? ArrowCodeBullish : ArrowCodeBearish); ObjectSetInteger(0, name, OBJPROP_COLOR, fvg.type == 1 ? BullishColor : BearishColor); ObjectSetInteger(0, name, OBJPROP_WIDTH, ArrowSize); } } } // Detect and draw iFVGs for (int m = 0; m < fvgCount; m++) { FVG fvg = fvgs[m]; string name = (fvg.type == -1 ? "iBullFVG_" : "iBearFVG_") + IntegerToString(fvg.startBar); if (ObjectFind(0, name) != -1) continue; double zoneTop = (fvg.type == 1) ? fvg.highVal : fvg.lowVal; double zoneBottom = (fvg.type == -1) ? fvg.lowVal : fvg.highVal; for (int i = fvg.endBar + 1; i < rates_total - 1; i++) { bool isInvalidated = false; double arrowPrice = 0; if (fvg.type == -1 && close[i] > zoneTop) { arrowPrice = low[i] - ArrowOffsetPoints * _Point; isInvalidated = true; } else if (fvg.type == 1 && close[i] < zoneBottom) { arrowPrice = high[i] + ArrowOffsetPoints * _Point; isInvalidated = true; } if (isInvalidated) { ObjectCreate(0, name, OBJ_ARROW, 0, time[i], arrowPrice); ObjectSetInteger(0, name, OBJPROP_ARROWCODE, (fvg.type == -1) ? ArrowCodeBullish : ArrowCodeBearish); ObjectSetInteger(0, name, OBJPROP_COLOR, (fvg.type == -1) ? iBullishColor : iBearishColor); ObjectSetInteger(0, name, OBJPROP_WIDTH, ArrowSize); break; } } } // Invalidate iFVGs if price closes beyond the original FVG zone for (int j = ObjectsTotal(0, -1, -1) - 1; j >= 0; j--) { string name = ObjectName(0, j); bool is_iBull = StringFind(name, "iBullFVG_") == 0; bool is_iBear = StringFind(name, "iBearFVG_") == 0; if (!is_iBull && !is_iBear) continue; int startBar = (int)StringToInteger(StringSubstr(name, StringLen(name) - StringLen(IntegerToString(LookbackBars)))); // Locate original FVG FVG matched; bool found = false; for (int i = 0; i < fvgCount; i++) { if (fvgs[i].startBar == startBar) { matched = fvgs[i]; found = true; break; } } if (!found) continue; double top = matched.highVal; double bottom = matched.lowVal; // Check candles after the original FVG’s end bar for (int i = matched.endBar + 1; i < rates_total; i++) { if ((is_iBull && close[i] < bottom) || (is_iBear && close[i] > top)) { ObjectDelete(0, name); break; } } } return rates_total; } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if (id == CHARTEVENT_OBJECT_CLICK) { if (StringFind(sparam, "BullFVG_") == 0 || StringFind(sparam, "BearFVG_") == 0) { MessageBox("To change indicator settings:\nRight-click on the chart -> Indicators List -> Select this indicator -> Properties", "Indicator Settings Info", MB_ICONINFORMATION); } } }
Hello Miguel hope you are doing well. I did try to use the OBJPROP_PRICE1 and 2 but it gives errors . can i share the same indicator that has IIFVG arrow whcih still wont delete once invalidated. If they can delete its when i shift to drawing IFVG boxes instead of arrow. Kindly help please will appreciate it so much. The fvg part is very okay drawing hidding and deleting is smooth. Just the issue with IFVG arrows that wont delete.
At first, we were talking about the version with rectangles, and the issue there is that you're using OBJPROP_PRICE, but for OBJ_RECTANGLE you need to use OBJPROP_PRICE1 and OBJPROP_PRICE2. Since that call fails, the zones never get deleted, even when they're clearly broken.
Then you slightly shifted the focus and mentioned arrows (OBJ_ARROW) with iFVGs, which is a different context.
In that case, deletion isn't really broken, you just need a proper function to loop through the chart objects and remove the invalidated arrows based on their name or status.
At first, we were talking about the version with rectangles, and the issue there is that you're using OBJPROP_PRICE, but for OBJ_RECTANGLE you need to use OBJPROP_PRICE1 and OBJPROP_PRICE2. Since that call fails, the zones never get deleted, even when they're clearly broken.
Then you slightly shifted the focus and mentioned arrows (OBJ_ARROW) with iFVGs, which is a different context.
In that case, deletion isn't really broken, you just need a proper function to loop through the chart objects and remove the invalidated arrows based on their name or status.
Can you help with please. Honestly it's been a week and I have been going in circles trying the rectangles and the rectangles which are just the same indicator with slight modifications. I have evn tried to use chatgpt to find a proper loop for the functions and looping but it hasn't worked. Kindly help me. Am totally stuck.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hey erveryone hope you guys are doing well.
I got an mlq5 code am trying to fix the deletion logic for invalidated logic but it is failing no matter waht i edit. Tried also chatgpt and deepseek but nothing fixes the issure. i have added candle lookbar, invalidation closes ,alert trigger deletes all of them but the broken zones stay solid.
It keeps old broken levels that are supposed to be deleted once price close below or above them even by one pip. Not sure why kindly someone look into it. Its very close to completion. I wll appreciate it very much.