Efficiency of indicators vs static

 

Has anybody ever done a study of whether it's more efficient (faster or fewer resources) to run an indicator twice vs storing the value in a static variable?

Specifically, I want to know if the Stochastics are moving up or down. Is it more efficient to run iStochastic() 4 times for each bar (2 for the previous bar), or store them in static variables to use in the comparison for the next bar?

int GetStochTrend(iBar, .....)
   {
      static datetime dtSaved;
      static double dMainSaved, dSignalSaved;

      int iPrev = iBar + 1;
      datetime dt = Time[iBar]
            , dtPrev = Time[iPrev];

      if ((dtPrev == dtSaved) && (dt > dtSaved))
         {
            dMainPrev = dMainSaved;      
            dSignal = dSignalSaved;
         }
      else
         {
            dMainPrev = iStochastic(......., iPrev);
            dSignalPrev = iStochastic(......., iPrev);
         }
      // code to get stochastics for ibar & comparison between dMain & dMainPrev, etc.
      
      if (iBar > 0)
         {
            // don't save stochcastics for bar 0
            dtSaved = dt;
            dtMainSaved = dtMain;
            dtSignalSaved = dtSignal;
         }
   }

This is not the complete function as most indicators will calculate for bar 1 with each tic in case the last few tics were missed while calculating, so there are really 2 sets of static variables to store 2 sets of previous calculations, but you get the idea.

This way I don't have to keep calculating the Stochastic for bar 1 with every tic, but I have to keep them in memory and I have to do more comparisons to decide whether it needs to be calculated or retrieved from memory.

Let me know if I wasn't clear.

 

> Has anybody ever done a study of whether it's more efficient (faster or fewer resources) to run an indicator twice vs storing the value in a static variable?

Definitely - anything you can <do once & store> will certainly save CPU cycles and shorten tick execution during live trading

So only do the minimum every tick, do some each bar, some each minute, whatever

-BB-

 
FoxGuy:
This way I don't have to keep calculating the Stochastic for bar 1 with every tic
  1. Saving the value at the start of a new bar will be slightly more efficient than the call repeated.
  2. If you're only looking at bar one or greater, then why are you running "every tic". Decide at the start of a new bar and your done.
    int start(){        static datetime Time0;
       if (Time0 == Time[0]) return(0); Time0 = Time[0];
       // New bar

 
WHRoeder:
  1. Saving the value at the start of a new bar will be slightly more efficient than the call repeated.
  2. If you're only looking at bar one or greater, then why are you running "every tic". Decide at the start of a new bar and your done.

When the indicator is first attached to a chart or the indicator is recompiled (which I'm doing a lot of since it's my first one), it calculates for every bar, so saving the previous bar saves having to recalculate it again on the next bar.

But once it's finished with every bar, it just does bar 1 & 0 on every tic (bar 1 because sometimes the indicator is busy when a tic at the end of the bar comes in).

 
BarrowBoy:

> Has anybody ever done a study of whether it's more efficient (faster or fewer resources) to run an indicator twice vs storing the value in a static variable?

Definitely - anything you can <do once & store> will certainly save CPU cycles and shorten tick execution during live trading

So only do the minimum every tick, do some each bar, some each minute, whatever

-BB-

Years ago someone once told me that it can take more time checking to make sure that the stored values are the correct ones than it would take to just recalculate them again.

In my example (where I really store 2 sets of values for bar2 and bar1 because sometimes the last few tics of a bar are missed because the indicator is busy), I have to ask for the date of the current bar and the previous bar, then compare dates to the values I have stored. And I have to check whether there's a new bar each tic. And when a newbar appears I have to move 3 values from bar1 stored values to bar2 stored values. Then at the end of the function I have to make sure that I'm not on bar0 (no point in wasting time saving bar0 - it has to be recalculated with every tic anyway) and since I'm saving 2 bars values I also have to make sure that I'm only saving values for bar1 (no point in saving bar2 values when it becomes bar3 because they will never be used again). There are more compares, but you get the point. If this isn't clear just ask and I'll go into more detail.

So all in all I may be spending more time verifying that I'm using the correct previous values than it would take to just recalculate them.

I was hoping that someone had done a study on how many "if (Some.Value == Some.Stored.Value)" I could do before it cancels out the time savings of not having to recalculate a value for a previous bar (or some similar study).

 
int GetTickCount( )
The GetTickCount() function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer.
Sample:
  int start=GetTickCount();
  // some hard calculations...
  Print("Calculation time is ", GetTickCount()-start, " milliseconds.");
 
ubzen:
int GetTickCount( )
The GetTickCount() function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer.
Sample:

I'm guessing that you're suggesting that I use GetTickCount() to determine if any ticks were missed since the last calculation.

My gut says that it would still be possible to miss a tick. If 2 ticks came in within 1 millisecond and the calculation took 1 millisecond then the 2nd tick could get missed. Also I would never trust that the calculation would always take only 1 millisecond to finish. I keep my browser open while I'm working and I download mq4 files that promise to teach me something, so my resources could get tied up.

Theoretically my resources could get tied up for 60 seconds which could screw up bar2 in a Period_M1 chart, but I'm not going to worry about that for now.

But I'm new to MT4. This is my 1st indicator so I'm not positive.

 
GetTickCount( ) is actually used to test speed efficiency. I'll suggest you do a set of calculations and check the time lapse from start to finish.
 
ubzen:

GetTickCount( ) is actually used to test speed efficiency. I'll suggest you do a set of calculations and check the time lapse from start to finish.

That makes more sense.

That's what I'll do if I can't find anybody who has done it already. It just means that I have to write 2 functions each time I want to find out if a particular indicator is efficient or not.

 
BarrowBoy:

> Has anybody ever done a study of whether it's more efficient (faster or fewer resources) to run an indicator twice vs storing the value in a static variable?

Definitely - anything you can <do once & store> will certainly save CPU cycles and shorten tick execution during live trading

So only do the minimum every tick, do some each bar, some each minute, whatever

-BB-

For anyone that's interested, it's faster to just calculate the previous bar along with the current bar when the indicator is first loaded. Saving the previous bar's values and then checking to make sure that you're using the correct values on the next bar adds about 15% onto the time it takes to calculate 20,000 bars. At least that what I got for calculating the Exponential MA for both 5 periods and 10 periods at the same time (to determine when they cross).

I wrote a function that could be used for any oscillator and then tested it on the EMA(5) and EMA(10). My function could handle 6 different oscillators at the same time (that way the EA could look for EMAs crossing, Stochastics going in the same direction, and MACD going in the same direction) so it had to do a scan through an array[5] looking for the correct set of values to use for the previous bar.

It's possible that writing a function for a specific oscillator might be faster if the function just assumed that the saved value was the correct one (rather than checking the date that was saved to make sure it's the correct values), but it's hard to believe that it could make up the 15% that my generic function added to the time.

When it was just calculating one tick, it took less than 1 millisecond to do the calculation either way.

Reason: