How to avoid wrong initialization of indicator with iBarShift

 

Hi all,

this time i come here with a question .. i dont see some mistakes .. but maybe late hour :-)

i was playing with iBarShift in an Indicator for OBV. in General is working not bad .

int i,nLimit,nCountedBars;
   nCountedBars=IndicatorCounted();
   if(nCountedBars>0) nCountedBars--;
   nLimit=Bars-nCountedBars-1;


  for(i=0; i<=nLimit; i++)
     {  
     int bs=iBarShift(NULL,TF,Time[i],false);       
     ExtOBVBuffer[i]=iOBV(NULL,TF,PRICE_CLOSE,bs);     
     }

but if i open a new chart in M5, put the indi with TF=15 on it, first time looks like this:

if i switch to M15 and after few seconds back to m5 looks ok like this:

so - i guess in the beginning are not enough data for M15 for the "bad looking".

Any idea how to avoid this?

Thanks and best reagrds from austria

 

hmmm...no one?

 

You need to have your indicator make an initial update call to the server to refresh the historical data in memory.

Here is the code I use for this:

      // Synchronize the memory-resident historical price data so that the EA and indicators on other timeframes have access to recent data
      if(SyncServerData==true)
         {
         for(i=1;i<=9;i++)
            { // i looping for M1-MN1 History Files
            switch(i)
               {
               case 1   :  ServerSyncTimeFrame=1;  break; // Synchronize M1 Timeframe data with the server
               case 2   :  ServerSyncTimeFrame=5;  break; // Synchronize M5 Timeframe data with the server
               case 3   :  ServerSyncTimeFrame=15;  break; // Synchronize M15 Timeframe data with the server
               case 4   :  ServerSyncTimeFrame=30;  break; // Synchronize M30 Timeframe data with the server
               case 5   :  ServerSyncTimeFrame=60;  break; // Synchronize M60 Timeframe data with the server
               case 6   :  ServerSyncTimeFrame=240;  break; // Synchronize M240 Timeframe data with the server
               case 7   :  ServerSyncTimeFrame=1440;  break; // Synchronize M1440 Timeframe data with the server
               case 8   :  ServerSyncTimeFrame=10080;  break; // Synchronize M10080 Timeframe data with the server
               case 9   :  ServerSyncTimeFrame=43200;  break; // Synchronize M43200 Timeframe data with the server
               default  :  Print("Error encountered in the SWITCH routine for setting the timeframe for server data synchronization"); return(0);// The expression did not generate a case value
               }
            
            j=0; // initialize the while loop counter
            while(j<10 && (iClose(CurrentSymbol,ServerSyncTimeFrame,2)==0 || GetLastError()==4066)) // call the iClose() function with a shift of 2 to ensure we sample the timeseries in a likely unsynchronized span
            {
               j++; // increment the while loop counter
               if(verbose==true) Print("Sync cycle ",j,": Sleeping for ",sleep_seconds," seconds to let the server synchronize with requested date for Period M",ServerSyncTimeFrame);
               Sleep(sleep_seconds*1000); // sleep to give the server time to update the local hst file
               }
            if(j==10)
               {
               Print("Failed to synchronize the hst data with the server after ",j," cycles and ",j*sleep_seconds," seconds");
               return(0);
               }
            }
         }
Obviously you need to define the requisite parameters and so on, and add a counter so that this process is only done once when the indicator is initially called/loaded because it only need be called once and then the data will be updated automatically thereafter until the indicator is unloaded or the terminal is shutdown.


You can use the attached indicator as a template. Copy it over to your indicator or paste your indicator into the start() and deinit() section. It'll take a little extra longer to fully load when first called (defined by the sleep_seconds value), but after that you should be good to go.

 
1005phillip:

You need to have your indicator make an initial update call to the server to refresh the historical data in memory.

Here is the code I use for this:

Obviously you need to define the requisite parameters and so on, and add a counter so that this process is only done once when the indicator is initially called/loaded because it only need be called once and then the data will be updated automatically thereafter until the indicator is unloaded or the terminal is shutdown.


You can use the attached indicator as a template. Copy it over to your indicator or paste your indicator into the start() and deinit() section. It'll take a little extra longer to fully load when first called (defined by the sleep_seconds value), but after that you should be good to go.


Nice idea!

Thx, i will give a try on the weekend :-)

 
FWI, I would have coded that switch differently
static int TF[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1
                  , PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };
for(i=0;i < ArraySize(TF);i++)
{ // i looping for M1-MN1 History Files
    ServerSyncTimeFrame=TF[i];
 
WHRoeder:
FWI, I would have coded that switch differently

It's recycled code from my chart timeframe assigner. When I run optimizations I like to have the chart timeframe assignable by integer 1-9 so I can just set the optimizer to backtest across that parameter space, then within the EA the integer is reassigned the actual chart timeframe by way of the switch. Once I had the switch already coded it's just copy-and-past from EA to EA ever since (throwing the loop iterator in front of it).
 

Hi,

I probe this code.

But I don't use it.

The Sleep(sleep_seconds*1000); function is not runing. Not sleep!

Why?

In the documentation: "The Sleep() function cannot be called from custom indicators since they calculate in the interface thread and may not decelerate it."

What is it?

Reason: