Announcement

Collapse
No announcement yet.

getBarStateInterval

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • getBarStateInterval

    Good Morning,

    The attached code is a demonstartion of computing a 1 minute, 3 period, end centered moving average 4 diferent ways. It was applied to a tick chart and produced 4 different results. Could you please explain how each value is calculated?

    Best Regards,

    Alan

    PHP Code:
    function preMain() {
        
        
    setStudyTitle("InTest");
        
    setCursorLabelName("MA1"0);
        
    setDefaultBarStyle(PS_SOLID0);
        
    setDefaultBarStyle(PS_SOLID1);
        
    setDefaultBarStyle(PS_SOLID2);
        
    setDefaultBarStyle(PS_SOLID3);
        
    setDefaultBarFgColor(Color.red0);
        
    setDefaultBarFgColor(Color.blue1);
        
    setDefaultBarFgColor(Color.green2);
        
    setDefaultBarFgColor(Color.yellow3);
        
    setDefaultBarThickness(30);
        
    setDefaultBarThickness(31);
        
    setDefaultBarThickness(32);
        
    setDefaultBarThickness(33);
        
    setPlotType(PLOTTYPE_LINE0);
        
    setPlotType(PLOTTYPE_LINE1);
        
    setPlotType(PLOTTYPE_LINE2);
        
    setPlotType(PLOTTYPE_LINE3);
       
        
    Symbol1 "$playback";
        
    Interval1 "1M";
        
    Interval2 "60S";
        
    }

    function 
    main() {

    var 
    vSymbol1 Symbol1+","+Interval1;
    pMA1 offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol1))),0);
    var 
    jMA1 pMA1.getValue(0);

    var 
    vSymbol2 Symbol1+","+Interval2;
    pMA2 offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol2))),0);
    var 
    jMA2 pMA2.getValue(0);

    if(
    getBarStateInterval("1")==BARSTATE_NEWBAR){

    var 
    vSymbol3 Symbol1+","+Interval1;
    pMA3 offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol3))),0);
    var 
    jMA3 pMA3.getValue(0);

    var 
    vSymbol4 Symbol1+","+Interval2;
    pMA4 offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol4))),0);
    var 
    jMA4 pMA4.getValue(0);
    }

    return new Array (
    jMA1jMA2jMA3jMA4);  


  • #2
    Re: getBarStateInterval

    Hi Alan2004,

    Originally posted by Alan2004
    Could you please explain how each value is calculated?
    In the Beginning... hmm... where to start?

    There are several differences here. What specifically are you looking for?

    Comment


    • #3
      Steve,

      1) Inside getBarStateInterval, the moving average is calculated twice using 1 minute and 60 second periods. Why does it produce different results in playback mode? Is one more accurate/reliable than the other?

      2) How is the calculation different when the same periods are used without getBar?

      3) Since all 4 are 1 minute moving averages of tick data and they produce 4 different results, I am trying to determine which is the most accurate/reliable for an application.

      Alan

      Comment


      • #4
        Alan,

        Thank you for the clarification. Further, thank you for posting your code, it makes it much easier to figure this stuff out. Now that I understand what you are asking, I took a look at your code and ran it in tick playback. There were several issues.

        A1 - you are re-initializing EFS2 objects every tick. This is inefficient and not required. You can declare them just once in the beginning of your code.

        A2 - you declared your interval as for 1 minute using "1M". It should be declared with a "1" or a numerical 1. The "M" is associated with monthly. While it works, I think it does because the number is in front of the "M", which is not a correct format for a monthly interval. FWIW, I made the same mistake.

        A3 - As the efs is executed, your values for jMA1 and jMA2 are re-established every tick. However, jMA3 and jMA4 are only defined when their associated getBarStateInterval is met. Therefore, for all the ticks between that (getBarStateInterval("1")==BARSTATE_NEWBAR) conditional will return a null to the chart. A partial solution to this is to define jMA3 and jMA4 as global variables so they maintain their previously defined values between bars. However, it is not a complete solution.

        A4 - When a new bar is defined, the current close is the first tick into the new bar. It may be the same as the close of the previous bar, it may not. In this example, you are using the low price. Therefore, on a new bar, close = low = high = open for the very first tick. There is a chance that the low of the previous bar is the same as the first low of a new bar, but it is often not the same. The way to address this is to plot jMA3 and jMA4 similar to jMA1 and jMA2.

        A5 - check this link, as there are differences in how the chart handles intervals of some electronically traded contracts ("60S" and minute intervals). http://forum.esignalcentral.com/show...9145#post79145 This may or may not have any affect on your chart depending on what you downloaded.

        Sorry I did not answer your questions in order. I believed fixing the problems with the code and going through some of the issues and concepts first was the best way to address the questions.

        I modified your script a little. Run this revised EFS and see if what I said makes sense. Move the lines for jMA3 and jMA4 outside the getBarStateInterval conditional and see what happens. Take a look at the times the debug statements output and see if they are always identical. Please try and see if you can figure out why some of the values are different (if they are) during tick playback.

        I hope this helps.

        PHP Code:
        function preMain() {
            
         
        setStudyTitle("InTest");
         
        setCursorLabelName("MA1"0);
         
        setDefaultBarStyle(PS_SOLID0);
         
        setDefaultBarStyle(PS_SOLID1);
         
        setDefaultBarStyle(PS_SOLID2);
         
        setDefaultBarStyle(PS_SOLID3);
         
        setDefaultBarFgColor(Color.red0);
         
        setDefaultBarFgColor(Color.blue1);
         
        setDefaultBarFgColor(Color.green2);
         
        setDefaultBarFgColor(Color.yellow3);
         
        setDefaultBarThickness(30);
         
        setDefaultBarThickness(31);
         
        setDefaultBarThickness(32);
         
        setDefaultBarThickness(33);
         
        setPlotType(PLOTTYPE_LINE0);
         
        setPlotType(PLOTTYPE_LINE1);
         
        setPlotType(PLOTTYPE_LINE2);
         
        setPlotType(PLOTTYPE_LINE3);
           
         
        Symbol1 "$playback";
         
        Interval1 "1";
         
        //Interval1 = "1M";
         
        Interval2 "60S";
        }

        var 
        bInit false;
        var 
        jMA3;var jMA4;
        function 
        main() {
         
         if(
        bInit == false)
         {
          var 
        vSymbol1 Symbol1+","+Interval1;
          
        pMA1 =  offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol1))),0);
          var 
        vSymbol2 Symbol1+","+Interval2;
          
        pMA2 =  offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol2))),0);
          var 
        vSymbol3 Symbol1+","+Interval1;
          
        pMA3 =  offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol3))),0);
          var 
        vSymbol4 Symbol1+","+Interval2;
          
        pMA4 =  offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol4))),0);

          
        bInit true;
         }
         if (
        getBarState() == BARSTATE_NEWBAR)
         {
          
        debugPrintln ("47 chart bar time = "+minute(0inv(Interval2))+":"+second(0inv(Interval2)));
         }
         var 
        jMA1 pMA1.getValue(0);
         var 
        jMA2 pMA2.getValue(0);
         
        //jMA3 = pMA3.getValue(0);
         //jMA4 = pMA4.getValue(0);

         
         
        if(getBarStateInterval(Interval1)==BARSTATE_NEWBAR){
          
        debugPrintln ("53 getBarStateInterval(1) bar time = "+minute(0inv(Interval1))+":"+second(0inv(Interval1) ));
          
        debugPrintln (" ");
          
        jMA3 pMA3.getValue(0); // using the first tick of the new bar
          
        jMA4 pMA4.getValue(0); // using the first tick of the new bar
         
        }
         
         return new Array (
        jMA1jMA2jMA3jMA4);  

        Comment


        • #5
          Steve,

          Thank you for the responce. I would first like to explore the comment on 1 minute and 60 second periods could produce different results. The following code is the modified version you sent back to me. I loaded this onto a 1 minute chart to get a better understanding of what is happining.

          When I run this code, I get 4 distictly different results. When I reload the EFS jMA1 is exactly the same as jMA3 and jMA2 is the same as jMA4. Why does the historical data get changed in playback after a reload? When I restart the playback, the 4 lines return.

          I am trying to calculate the moving average of the lowest low in the 1 minute bar but it is returnig 4 different results. When I use data export to look at the actual low and the calculated moving avaerages, the only one that is correct is jMA1. The last value appears to equal the second to the last average and changes when the bar is completed. Is this correct? jMA1 uses 1 minute data and not 60 second data and is changed when reloaded.

          Why on a 1 minute chart are the 1 minute and 60 second calculations so different?

          Best Regards,

          Alan










          function preMain() {

          setStudyTitle("InTest1");
          setCursorLabelName("MA1", 0);
          setDefaultBarStyle(PS_SOLID, 0);
          setDefaultBarStyle(PS_SOLID, 1);
          setDefaultBarStyle(PS_SOLID, 2);
          setDefaultBarStyle(PS_SOLID, 3);
          setDefaultBarFgColor(Color.red, 0);
          setDefaultBarFgColor(Color.blue, 1);
          setDefaultBarFgColor(Color.green, 2);
          setDefaultBarFgColor(Color.yellow, 3);
          setDefaultBarThickness(3, 0);
          setDefaultBarThickness(3, 1);
          setDefaultBarThickness(3, 2);
          setDefaultBarThickness(3, 3);
          setPlotType(PLOTTYPE_LINE, 0);
          setPlotType(PLOTTYPE_LINE, 1);
          setPlotType(PLOTTYPE_LINE, 2);
          setPlotType(PLOTTYPE_LINE, 3);

          Symbol1 = "$playback";
          Interval1 = "1";
          //Interval1 = "1M";
          Interval2 = "60S";
          }

          var bInit = false;
          var jMA3;var jMA4;

          function main() {

          if(bInit == false)
          {
          var vSymbol1 = Symbol1+","+Interval1;
          pMA1 = offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol1))) ,0);
          var vSymbol2 = Symbol1+","+Interval2;
          pMA2 = offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol2))) ,0);
          var vSymbol3 = Symbol1+","+Interval1;
          pMA3 = offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol3))) ,0);
          var vSymbol4 = Symbol1+","+Interval2;
          pMA4 = offsetSeries(eval(sma)(3,eval(low)(sym(vSymbol4))) ,0);

          bInit = true;
          }
          if (getBarState() == BARSTATE_NEWBAR)
          {
          debugPrintln ("47 chart bar time = "+minute(0, inv(Interval2))+":"+second(0, inv(Interval2)));
          }
          var jMA1 = pMA1.getValue(0);
          var jMA2 = pMA2.getValue(0);
          //jMA3 = pMA3.getValue(0);
          //jMA4 = pMA4.getValue(0);


          if(getBarStateInterval(Interval1)==BARSTATE_NEWBAR ){
          debugPrintln ("53 getBarStateInterval(1) bar time = "+minute(0, inv(Interval1))+":"+second(0, inv(Interval1) ));
          debugPrintln (" ");
          jMA3 = pMA3.getValue(0); // using the first tick of the new bar
          jMA4 = pMA4.getValue(0); // using the first tick of the new bar
          }

          return new Array ((jMA1), (jMA2), jMA3, jMA4);
          }

          Comment


          • #6
            Hi Alan,

            You are most welcome. I hope you took a look at the link I provided, for continuity, here is the last post in that thread where Alex provided a very good explanation:
            Originally posted by Alexis C. Montenegro
            John
            What you are seeing is due to how an efs executes in minute based charts with some electronically traded contracts (ES and NQ for example). Under those conditions an efs will execute only when
            - Current trade price is different than the previous trade price.
            - Current trade price is at the bid and previous trade was at the ask or vice versa. The two trade prices can be the same in this instance.
            With tick based charts (Tick, Volume, Seconds or Price-change) instead an efs executes on every trade so a solution could be to use (for example) 60S in lieu of 1 minute.
            Alex
            Please try this. Download 1 day of ticks for ES #F (using the tick downloader), and use the tick replay feature to play back a 60 second chart with the EFS performance monitor enabled. Record the number of calls to the efs that occured during this day. Now, reset the chart and performance monitor. Change the chart interval to 1 minute and play back the chart again. You will see that there are more calls in the 60 second chart than the 1 minute chart. That is because a non-tick interval chart (1 minute) is handled differently than a tick chart (60 sec). Further, when playing back these charts, look at the time returned for a 60 second timeframe closely, you will see that they are not always at the same time as the 1 minute time. I am sure you understand that small differences in the low values can occur and how this would explain why the moving averages may be slightly different.

            So, having gone through these reasons, I hope this helps to understand why there are sometimes very small differences between the 60 second and 1 minute moving averages. I typically use a 1 minute interval, as it requires less resources than a 60 second chart.

            As far as which is correct, I will say that they all are. These calculations are returning the specific moving average that you are requesting.

            Regarding JMA3 and JMA4, the differences between the live data and the historical data are due to what I explained in "A4" below. Once live data is being processed, JMA3 and JMA4 are not the moving averages calculated at the end of each bar, rather, they are the moving averages of the first tick of a new bar.

            getBarStateInterval(Interval1)==BARSTATE_NEWBAR
            is, as it name indicates, a new bar. When this event occurs, the chart has already advanced to the new bar. If you perform the calculation of moving average for this bar at this point, the low value which you use in your calculation is not the price at the end of the bar, rather, it is the open price.

            When you reload the chart, you have the advantage of knowing what the open, high, low and close of each bar in the chart is. That is why the values are equal, after reload, you are truly calculating the moving average of the low of each bar. When you are processing live data and you perform the calculation on the first tick of a new bar, you are asking for the moving average of the open, even though you specified the low. Remember on a new bar, close = low = high = open for the very first tick. How can the computer possibly know what the low of the bar is going to be at the very beginning of the bar? That is why I indicated in my post that you should Move the lines for jMA3 and jMA4 outside the getBarStateInterval conditional and see what happens.

            I hope this helps.

            Comment


            • #7
              Steve,

              Thank you for the indepth comments. They are greatly appreciated.

              Let me try a different approach. Lets leave the tick chart and getBarStateIntervel aside and only focus on jMA1 and jMA2. The attached chart is on a 1 minute basis and I applied the EFS in the last post excluding the return of jMA3 and jMA4.

              Note the 1 minute and 60 second averages are diferent by 3 points on the DOW. I used the data export for the chart and hand calculated the 3 period moving average. The 1 minute interval is correct and the 60 second is incorrect based on the data in the table. Based on Alex's post, I take away that the 60 second interval should be the more correct method when in fact it is incorrect based on the data table.

              I am assuming the data in the data table represents the lowest low for the 1 minute period. What data is the 60 second average using that creates the difference? Since the getBarStateInterval is not being used, the opening value should not be an issue.

              Your assistance is greatly appreciated.

              Best Regards,

              Alan
              Attached Files

              Comment


              • #8
                Alan
                The differences you are seeing are caused by the different time stamps of the 1 minute and the 60 seconds chart as Steve has already explained to you.
                For example the same bar that on a 1 minute chart is time stamped 11:23 (which is actually 11:23:00) could be time stamped 11:23:01 on the 60 seconds chart. When this happens the efs engine has to adjust the plot of the average because in order to maintain constant synchronization across intervals it needs to match each value to the appropriate time stamp. Since in that case it cannot find a time stamp on the 60 seconds interval that matches exactly the 1 minute time stamp the efs engine uses the last known value of the average based on the 60 seconds interval ie the value at the bar of 11:22:xx which at that point causes the difference in the plots.
                On those bars in which the time stamps are instead identical ie 11:23 on the 1 minute chart and 11:23:00 on the 60 seconds chart you will see that the values of the averages will match perfectly.
                Alex

                Comment


                • #9
                  Alex,

                  Thank you for the clarification. Between Steve and your comments I think I understand. Let me play back in my terms my understanding to insure I am clear because I think I define some of the terms slightly differently.

                  When I refer to a 1 minute chart, I am thinking of a minute as defined on a clock. An accumulator looks at the tick data for the lowest low during this period of time and that is what is reported on the data export table from a 1 minute chart. A 3 period moving average of the data can only produce 1 result which I confirmed by calculating it by hand and it matches only jMA1. The 60 second calculations (which are not always the same as 1 minute) are preformed differently if there is a sync. issue. I do not want to say they are wrong, they are just calculated differently due to the sync. issue. With this said, is there any advatage to using 60 seconds rather than 1 minute for the Dow YM H6 as a symbol? Your referenced post speaks to potential problems if you do not use 60 seconds. However by using 60 seconds it introduces a different calculation method. Is this just a trade off of recognising all ticks versus a different calculation method? How do I know if this symbol has the same problems? The reason for the detailed request is if I am trading with a target profit of 20 points, a 3 point discrepancy in calculations could generate nearly a 15% differance. This is not small.

                  I greatly appreciate both Steve and your time in helping me understand the issues. A 15% differance is very leveraging. Also as you look at the smoothness of the plots, the jMA1 is much smoother than the jMA2. Algoithims that detect reversals on short periods of time could be missled by the shop that occures in jMA2.

                  Best Regards

                  Alan

                  Comment


                  • #10
                    Alan,

                    You are most welcome. I would propose to you that any potential system that you develop should not have measured differences in performance of the magnitude you mention based on when a 1 minute bar begins. Rather it seems as if the system is more "fitted" or "tuned" to the historical data. In terms of reliability and future performance, my sincere feedback to you is to be cautious. I would expect any trading system that would perform reliably would do so with much less dependancy on the specific time period used. This is my two cents worth.

                    Comment

                    Working...
                    X