if (Close[j + 1] > rectangleLongPrice[j] && Close[j] < rectangleLongPrice[j]) { ObjectDelete("Bullish" + DoubleToStr(j, 0));
Do not use series index in object names, as they are not unique. As soon as a new bar starts, you will be trying to create a new name (e.g., “name0”), same, existing, previous, name (e.g., “name0” now on bar one.)
Use time (as int) or a non-series index:
#define SERIES(I) (Bars - 1 - I) // As-series to non-series or back.
Do not use series index in object names , as they are not unique. As soon as a new bar starts, you will be trying to create a new name (e.g., “name0”), same, existing, previous, name (e.g., “name0” now on bar one.)
Use time (as int ) or a non-series index:
Thanks, I tried adding the price of the corresponding bar to the name. Now I've tried another approach, saving the name in the array, then fetching the price with Objectget. With a comment I can see that the name is saved in the array, but when it comes to getting the prices, if I try to print them with a comment they are not exact.. This is the code I use in a while loop inside oncalculate to create the zones and save the name :
if (isCandleSequenceLong) { string LongName = "Bullish" + DoubleToString (Low[i + 2 ], 0 ); ObjectCreate (LongName, OBJ_RECTANGLE , 0 , Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ]); ObjectSet(LongName, OBJPROP_COLOR , Lime); if (!FillZone) ObjectSet(LongName, OBJPROP_BACK , false ); rectangleLongName[i] = LongName; isCandleSequenceLong = false ; } if (isCandleSequenceShort) { string ShortName = "Bearish" + DoubleToString (High[i + 2 ], 0 ); ObjectCreate (ShortName, OBJ_RECTANGLE , 0 , Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ]); ObjectSet(ShortName, OBJPROP_COLOR , Red); if (!FillZone) ObjectSet(ShortName, OBJPROP_BACK , false ); rectangleShortName[i] = ShortName; isCandleSequenceShort = false ; }
And this is the function that should eliminate them :
void DeleteBrokeZone() { for ( int j = 0 ; j < ObjectsTotal ()- 1 ; j++) { double LongPrice = ObjectGet(rectangleLongName[j],OBJPROP_PRICE2); double ShortPrice= ObjectGet(rectangleShortName[j],OBJPROP_PRICE1); Comment (LongPrice); if (Close[j + 1 ] > LongPrice && Close[j] < LongPrice ) { if (!ObjectDelete (rectangleLongName[j])) Print ( "Error:" + rectangleLongName[j]); } if (Close[j + 1 ] < ShortPrice && Close[j] > ShortPrice) { if (!ObjectDelete (rectangleShortName[j])) Print ( "Error:" + rectangleShortName[j]); } } }
The weird thing is that it works in backtest, but not in live! ty
Can anyone help me? i am really stuck on this code
thanks, what's the problem of checking at each new bar ?
I modified the code and now I'm getting some results, that is, even in the live market it eliminates some invalid zones, but unfortunately not all. I can't figure out why some zones that meet the deletion criteria are not deleted...
if (isCandleSequenceLong) { static int longcounter = 1000 ; string LongName = "Bullish" + IntegerToString (longcounter, 0 ); ObjectCreate (LongName, OBJ_RECTANGLE , 0 , Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ]); ObjectSet(LongName, OBJPROP_COLOR , Lime); if (!FillZone) ObjectSet(LongName, OBJPROP_BACK , false ); rectangleLongName[longArrayCounter] = LongName; isCandleSequenceLong = false ; longcounter++; longArrayCounter++; } if (isCandleSequenceShort) { static int shortcounter = 1000 ; string ShortName = "Bearish" + IntegerToString (shortcounter, 0 ); ObjectCreate (ShortName, OBJ_RECTANGLE , 0 , Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ]); ObjectSet(ShortName, OBJPROP_COLOR , Red); if (!FillZone) ObjectSet(ShortName, OBJPROP_BACK , false ); rectangleShortName[shortArrayCounter] = ShortName; isCandleSequenceShort = false ; shortcounter++; shortArrayCounter++; } void DeleteBrokeZone() { for ( int i = 0 ; i < ArraySize (rectangleLongName); i++) { if ( StringLen (rectangleLongName[i]) > 0 ) { if ( ObjectFind ( NULL , rectangleLongName[i]) != - 1 ) { price1 = ObjectGetDouble ( 0 , rectangleLongName[i], OBJPROP_PRICE1); price2 = ObjectGetDouble ( 0 , rectangleLongName[i], OBJPROP_PRICE2); if (Close[i] < price2) { if (! ObjectDelete ( 0 , rectangleLongName[i])) { Print ( "Error deleting Long object: " + rectangleLongName[i]); } else Print ( "Deleted Long object: " + rectangleLongName[i]); rectangleLongName[i] = "" ; RefreshRates(); } } } } for ( int x = 0 ; x < ArraySize (rectangleShortName); x++) { if ( StringLen (rectangleShortName[x]) > 0 ) { if ( ObjectFind ( NULL , rectangleShortName[x]) != - 1 ) { price1 = ObjectGetDouble ( 0 , rectangleShortName[x], OBJPROP_PRICE1); price2 = ObjectGetDouble ( 0 , rectangleShortName[x], OBJPROP_PRICE2); if (Close[x] > price1) { if (! ObjectDelete ( 0 , rectangleShortName[x])) { Print ( "Error deleting Short object: " + rectangleShortName[x]); } else Print ( "Deleted Short object: " + rectangleShortName[x]); rectangleShortName[x] = "" ; RefreshRates(); } } } } }
thanks, what's the problem of checking at each new bar ?
I modified the code and now I'm getting some results, that is, even in the live market it eliminates some invalid zones, but unfortunately not all. I can't figure out why some zones that meet the deletion criteria are not deleted...
Thanks Dominik, I tweaked the if and for loops nestings a bit but that didn't fix the problem sadly, I'm really stuck on this code.
Thanks Dominik, I tweaked the if and for loops nestings a bit but that didn't fix the problem sadly, I'm really stuck on this code.
OK, I have coded it up for you, but you need to figure it out on your own, as I have not checked the code, I just typed it!!!
struct my_zones { double break_level; string obj_name; bool short_zone; my_zones() : break_level(0.0), obj_name(""), short_zone(false) { }; }; my_zones arr_zones[]; int zone_count = 0; int delete_count = 0; int obj_count = 0; int OnCalculate() { // Create zones on chart ResetLastError(); if(isCandleSequenceLong) { const string obj_name = DrawRectangle("Bullish", Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ], Lime, (!FillZone)); if( (_LastError != 0) || (obj_name == "") ) { printf("Error drawing object to chart. ErrNo: %i", _LastError); ResetLastError(); } else { zone_count = ArrayResize(arr_zones, zone_count + 1, 500); arr_zones[zone_count - 1].break_level = Low[i + 2 ]; arr_zones[zone_count - 1].obj_name = obj_name; isCandleSequenceLong = false; } } if(isCandleSequenceShort) { const string obj_name = DrawRectangle("Bearish", Time[i + 3 ], High[i + 2 ], EMPTY_VALUE , Low[i + 2 ], Red, (!FillZone)); if( (_LastError != 0) || (obj_name == "") ) { printf("Error drawing object to chart. ErrNo: %i", _LastError); ResetLastError(); } else { zone_count = ArrayResize(arr_zones, zone_count + 1, 500); arr_zones[zone_count - 1].break_level = High[i + 2 ]; arr_zones[zone_count - 1].obj_name = obj_name; arr_zones[zone_count - 1].short_zone = true; isCandleSequenceShort = false; } } // Validate zones CheckZoneBreaking(Close[i]); } const string DrawRectangle(const string obj_name, const datetime point_a_t, const double point_a_p, const datetime point_b_t, const double point_b_p, const color obj_color, const bool filled) { const string _obj_name = StringFormat("%s_%i", obj_name, obj_count++); bool err = false; err = !ObjectCreate(ChartID(), _obj_name, OBJ_RECTANGLE, 0, point_a_t, point_a_p, point_b_t, point_b_p); err |= (!err) && !ObjectSetInteger(ChartID(), _obj_name, OBJPROP_COLOR, obj_color); err |= (!err) && !ObjectSetInteger(ChartID(), _obj_name, OBJPROP_BACK, filled); return((err) ? "" : _obj_name); } void CheckZoneBreaking(const double close_price) { // Check all zones for(int idx = zone_count - 1; (idx > -1) && !_StopFlag; idx--) { if( (arr_zones[idx].short_zone) && (arr_zones[idx].break_level < close_price) ) { ObjectDelete(arr_zones[idx].obj_name); arr_zones[idx].obj_name = ""; arr_zones[idx].break_level = DBL_MAX; delete_count++; } else if( (!arr_zones[idx].short_zone) && (arr_zones[idx].break_level > close_price) ) { ObjectDelete(arr_zones[idx].obj_name); arr_zones[idx].obj_name = ""; arr_zones[idx].break_level = 0.0; delete_count++; } } // Remove deleted if(delete_count > 250) { int ptr = 0; for(int idx = 0; (idx < zone_count) && !_StopFlag; idx++) { if(arr_zones[idx].obj_name == "") { continue; } arr_zones[ptr] = arr_zones[idx]; ptr++; } delete_count = 0; zone_count = ArrayResize(arr_zones, ptr, 500); } // Return return; }
EDIT:
I fixed a few typos.
OK, I have coded it up for you, but you need to figure it out on your own, as I have not checked the code, I just typed it!!!
EDIT:
I fixed a few typos.
Thank you very much, it's a code that I can't understand probably due to inexperience (for example, never used structures), I will study it well and try to implement
Edit : It seems your solution of calling the function passing the Close[i] in oncalculate fixed the problems I had without changing anything else! thanks!!!Thank you very much, it's a code that I can't understand probably due to inexperience (for example, never used structures), I will study it well and try to implement
Edit : It seems your solution of calling the function passing the Close[i] in oncalculate fixed the problems I had without changing anything else! thanks!!!![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Thanks to whoever can help me!