Why does For Loop mess up Object Create?

 

MetaTrader4 v4.00 Build 1260
Tested on MetaQuotes Data from 2020.06.15 to 2020.06.16 on EURUSD M1

Using a For Loop Operator and ObjectCreate(), we create a VLine the first time a candle has had a higher low and a higher high than iBar1 (last finished candle).

Method 1 doesn't work even though it reports the correct x before and after the object create function, while method 2 works while reporting an incorrect x value both before and after the object create function.

As per method 1; why does Object Create not use the x variable as the Print() suggests and we instead need to reverse the For Loop (as per method 2) just to get the Object Create function to correctly use the desired x value as originally intended?


//+------------------------------------------------------------------+
//|                                             newforumquestion.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
// MetaTrader4 v4.00 Build 1260
// Tested on MetaQuotes Data 2020.06.15 

// Using a For Loop, I get the first time a candle has had a higher low and a higher high than iBar1 (last finished candle). Method 1 doesnt work even though it reports the correct x before and after the object create function, while method 2 works while reporting an incorrect x value both before and after the object create function. Why does Object Create not use the x variable as logic would suggest and we instead need to reverse the For Loop just to get the Object Create function to correctly use the desired x value as originally intended? 

   //for(int x=20; x>=1; x--) // method 1
   //  {
   //   if(iLow(_Symbol,PERIOD_CURRENT,x)>iLow(_Symbol,PERIOD_CURRENT,1) && iHigh(_Symbol,PERIOD_CURRENT,x)>iHigh(_Symbol,PERIOD_CURRENT,1))
   //     {
   //      Print("x before object create ",x);
   //      ObjectCreate(ChartID(),"NewVLine",OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,x),iHigh(_Symbol,PERIOD_CURRENT,x),iTime(_Symbol,PERIOD_CURRENT,1),iLow(_Symbol,PERIOD_CURRENT,1));
   //      Print("x after object create",x);
   //     }
   //  }

   for(int x=1; x<=20; x++) // method 2 WHY DOES THIS WORK INSTEAD? WHY DOES THE NORMAL FOR LOOP THAT YIELDS THE CORRECT X VALUES MESS UP THE OBJECT CREATE LIKE THIS? WHY DO WE NEED TO REVERSE THE FOR LOOP TO ITERATE THE OTHER WAY AROUND IN ORDER TO GET OBJECT CREATE TO USE THE CORRECT X VALUE?
     {
      if(iLow(_Symbol,PERIOD_CURRENT,x)>iLow(_Symbol,PERIOD_CURRENT,1) && iHigh(_Symbol,PERIOD_CURRENT,x)>iHigh(_Symbol,PERIOD_CURRENT,1))
        {
         Print("x before object create ",x);
         ObjectCreate(ChartID(),"NewVLine",OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,x),iHigh(_Symbol,PERIOD_CURRENT,x),iTime(_Symbol,PERIOD_CURRENT,1),iLow(_Symbol,PERIOD_CURRENT,1));
         Print("x after object create",x);
        }
     }
  }
//+------------------------------------------------------------------+
 

You can not create the same object again (4200) you have to either delete the old object first or give the new object a different name, or you can check the existence of the object before you create it.

ERR_OBJECT_ALREADY_EXISTS 4200 Object already exists.

If you want to move it use ObjectMove()  or ObjectSetDouble() etc. to assign the object it's new values.

Documentation on MQL5: Object Functions / ObjectMove
Documentation on MQL5: Object Functions / ObjectMove
  • www.mql5.com
An asynchronous call is always used for ObjectMove(), that is why the function only returns the results of adding the command to a chart queue. In this case, true only means that the command has been successfully enqueued, but the result of its execution is unknown. To check the command execution result, you can use a function that requests...
 
nadiawicket:

MetaTrader4 v4.00 Build 1260
Tested on MetaQuotes Data from 2020.06.15 to 2020.06.16 on EURUSD M1

Using a For Loop Operator and ObjectCreate(), we create a VLine the first time a candle has had a higher low and a higher high than iBar1 (last finished candle).

Method 1 doesn't work even though it reports the correct x before and after the object create function, while method 2 works while reporting an incorrect x value both before and after the object create function.

As per method 1; why does Object Create not use the x variable as the Print() suggests and we instead need to reverse the For Loop (as per method 2) just to get the Object Create function to correctly use the desired x value as originally intended?


Try something like this

 ObjectCreate(ChartID(),"NewVLine_"+IntegerToString(x),OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,x),iHigh(_Symbol,PERIOD_CURRENT,x),iTime(_Symbol,PERIOD_CURRENT,1),iLow(_Symbol,PERIOD_CURRENT,1));
 
Marco vd Heijden:

You can not create the same object again (4200) you have to either delete the old object first or give the new object a different name, or you can check the existence of the object before you create it.

ERR_OBJECT_ALREADY_EXISTS 4200 Object already exists.

If you want to move it use ObjectMove()  or ObjectSetDouble() etc. to assign the object it's new values.

THX!! Great to know its handled like that. Didn't even suspect there was an Error so I didn't check last error. Will do always no matter what next time.
 
  1. nadiawicket:
             ObjectCreate(ChartID(),"NewVLine",OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,x),iHigh(_Symbol,PERIOD_CURRENT,x),iTime(_Symbol,PERIOD_CURRENT,1),iLow(_Symbol,PERIOD_CURRENT,1));
    

    You can only create one of a given name ("NewVLine")

  2. Fernando Morales: Try something like this
     ObjectCreate(ChartID(),"NewVLine_"+IntegerToString(x),OBJ_VLINE,0,iTime(_Symbol,PERIOD_CURRENT,x),iHigh(_Symbol,PERIOD_CURRENT,x),iTime(_Symbol,PERIOD_CURRENT,1),iLow(_Symbol,PERIOD_CURRENT,1));

    You can't use an as-series index in 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.