Announcement

Collapse
No announcement yet.

multi-timframe question

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

  • multi-timframe question

    I have written a script that correctly computes support and resistance values for R2, R1, PP, S1, S2 values for daily, weekly, monthly, quarterly, semi-annual and annual timeframes. This part is working. The data is presented as a non-price study as a table. So far so good as the table produces the proper data.

    Then I test each value in the table for proximity (within 0.5%) of any other value in the table. I then format each table cell foreground and background font colors depending if the values are close to each other.

    My problem is knowing when each of the daily, weekly, monthly, quarterly, semi-annual and annual calculations have completed before I test the results for proximity. I have found that function main() is running 301 times. I really only want it to run once and then compute proximity of all of the values on the six timeframes.

    eSignal knows about barstate. But I am operating on 6 timeframes. I had to construct quarterly, semi-annual and annual HLC data from monthly data.

    I would like pointers on how to proceed. Even if I had a time delay function that says wait two minutes and then compute proximity I might get by. But right now I don't know how to determine when all of my prior calculations have completed before I start a proximity test step.

    Mike Scott
    Tarzana, CA
    ....Mike

  • #2
    Mike Scott

    I am unclear about a few items that may have a bearing on your question.

    What time frame is on the chart?

    You said main() ran 301 times, do you have 301 bars of data by any chance?

    Also, the non-price study you see is for the last bar on the chart, are you trying to see previous values?

    Comment


    • #3
      multi-timeframe question

      David Loomis,

      It is possible that I have 301 bars of data. I don't really know as I am working in six time frames and none of the data I use is contained in the chart except perhaps yesterday's HLC. How would I know how many bars I am working with. The chart is currently a daily and it might well show 301 bars, if so I need to work some more on this. The non-price study does not use the last bar of the chart at all.

      The calculation looks up monthly historical HLC quotes for each month of the prior year (12-2008 values based on the current date in December 2009), each monthly quote of the prior semester (6 values in the first half of 2009 based on current date), each monthly quote of the prior quarter (3 values in the 3rd quarter 2009) as well as the last monthly quote (November 2009) and weekly quote (last week) and prior daily quote. All of these dates will change as we move to the next year/quarter/month. All script calculations are based on these retrieved values for the symbol and associated interval.

      I don't really know why my script runs 301 times but as you suggest it may be because of the number of bars on the daily chart.

      Formula script is attached and thank you for engaging.

      Mike Scott
      Tarzana, CA
      Attached Files
      ....Mike

      Comment


      • #4
        Mike,

        When an EFS study is first added, main() is called for each bar on the chart, starting with the oldest and ending with the latest bar. Usually, a chart has about 300 bars to start with, which is why you're seeing main() being called ~300 times.

        After that main() is called when the latest bar is updated (a trade occurs) and when a bar is "complete" (and a new bar is created).

        Most EFS studies process each bar as main() is called. For example,
        PHP Code:
        function main() {
            
        // process price bar...
            
        debugPrintln (barStateAsString (getBarState()) + ", bar: " getCurrentBarIndex() + ", last price: " close());

            
        // add real processing here...
        }


        // utility function to get barState number as a string:
        function barStateAsString (barState) {
            if (
        barState == BARSTATE_CURRENTBAR) {
                return 
        "BARSTATE_CURRENTBAR";
            }
            else if (
        barState == BARSTATE_NEWBAR) {
                return 
        "BARSTATE_NEWBAR";
            }
            else if (
        barState == BARSTATE_ALLBARS) {
                return 
        "BARSTATE_ALLBARS";
            }
            else {
                return 
        barState;    // return a number
            
        }

        Some studies ignore calls to main() for past bars and do all processing only when main() is called for the latest bar. Example,
        PHP Code:
        function main() {
            
        // ignore all but latest price bar
            
        if (getCurrentBarIndex() != 0) return;

            
        // process price bar...
            
        debugPrintln (barStateAsString (getBarState()) + ", bar: " getCurrentBarIndex() + ", bar's closing price: " close());

            
        // add real processing here...

        It seems your study is more static and doesn't care about bars on the chart, the "latest" price, etc. If that's the case, I'd do something like:
        PHP Code:
        var allBarsInProgress false;

        function 
        main() {
            
        // see if start of chart bars display or "refresh"
            
        if (getBarState() == BARSTATE_ALLBARS) {
                
        allBarsInProgress true;
            }

            
        // ignore unless chart is being loaded/reloaded
            // and last price bar
            
        if ((! allBarsInProgress) || (getCurrentBarIndex() != 0)) {
                return;
            }
            
        allBarsInProgress false;

            
        // process price bar...
            
        debugPrintln (barStateAsString (getBarState()) + ", bar: " getCurrentBarIndex() + ", bar's closing price: " close());

            
        // add real processing here...

        The last example above will [usually] only run main() ONCE, and it will do it at the right time (after the chart is loaded). However, it will rerun your study if the chart is refreshed, etc.

        You might want to run the above 3 examples to get a feel for when main() is called. (They're complete EFS programs - you don't need a preMain().) The first will print about 300 lines, then print a line per trade (if trading is going on). Second one will print one line, then a line for each new trade. Last one will only print one line, even if trading is going on.

        (I may be wrong, but I believe your function getQuarter(num) ALWAYS sets nQtrIndex to -3 and nSemiIndex to -6. nQtrIndex = -(vMonth % 3) - 1; or something like that is probably what you want.)
        Last edited by shortandlong; 12-29-2009, 05:50 PM.

        Comment


        • #5
          multi-timeframe question

          Thankyou Short and Long for the detailed reply. I modified my efs to implement the following. I found that this will run main two times which I find curious.

          function main(parameters) {

          var nIndex = getCurrentBarIndex();
          var nState = getBarState();

          if(nState == BARSTATE_NEWBAR && nIndex == 0) {

          //Calculate pivots, support and resistance values
          etc...
          }

          I will try your example and report back. This is the most difficult script I have attempted and bar state has been confusing to me. New script attached. You will notice that I have a debug switch to change interations of the primary loop from 2 to 1 time so that I can see what was happening.

          Mike Scott
          Tarzana, CA
          ....Mike

          Comment


          • #6
            The code you posted:
            PHP Code:
            function main() {
                var 
            nIndex getCurrentBarIndex();
                var 
            nState getBarState();

                if(
            nState == BARSTATE_NEWBAR && nIndex == 0) {
                    
            // processing...
                
            }

            ...will do processing once when the study is loaded or chart refreshed AND EACH TIME A NEW BAR IS ADDED as time goes by. For daily charts this may be what you want. Note, however, that for a 1 minute chart processing will be done every minute.

            There is a "feature" (which I've complained about in the past - see Click Here) where main() is called for all bars MULTIPLE times if the number of bars is over about 600 or so. Whether this happens doesn't seem to follow a pattern - at least I haven't figured it out...
            Last edited by shortandlong; 12-29-2009, 06:18 PM.

            Comment


            • #7
              multi-timeframe question

              Thank you Short and Long,

              I implemented your last suggested code and it may be working.
              I need to test on other platforms that showed different results using my original code. I could not implement your debugPrintln as it didn't pass the syntax checker. I tried to figure out what you were doing and didn't get it. So I commented out the code. This is the line:

              debugPrintln (barStateAsString (getBarState()) + ", bar: " + getCurrentBarIndex() + ", bar's closing price: " + close());

              What did you mean my barStateAsString? Do I need to put quotes around this followed by a comma? Or did yo mean to convert what ever followed to a string using some conversion function?

              Mike Scott
              Tarzana, CA
              ....Mike

              Comment


              • #8
                Re: multi-timeframe question

                Hi Mike,

                Using debugPrintln() is a great idea for troubleshooting problems in your code. shortandlong's note regarding the combined logic is correct, ...will do processing once when the study is loaded or chart refreshed AND EACH TIME A NEW BAR IS ADDED as time goes by.

                To help make sense of getCurrentBarIndex() and getBarState(), I wrote an efs entitled barState Play.efs that is well commented and has numerous debugPrintln() outputs that you may find helpful. It is in the Demo Concepts folder of my FileShare.

                I studied your code earlier in the day and found a couple of errors. One is that you did not define the variable nSemiIndex as a global variable and you should. Also, your conditionals are formatted incorrectly in your getQuarter() function.

                Finally, I recommend writing a separate function for your pivot calculations and calling it under each interval using the EFS2 efsInternal function. This would reduce the number of external interval calls in your code and make it more efficient. Here is how I wrote the function.

                PHP Code:
                function mikesPivots(){
                 var 
                hi=high(-1);
                 var 
                lo=low(-1);
                 var 
                cls=close(-1);
                 var 
                pivot0=(cls+hi+lo)/3;
                 var 
                pivotR1=2*pivot0-lo
                 var 
                pivotS1=2*pivot0-hi
                 var 
                pivotR2=pivot0-(pivotS1-pivotR1);
                 var 
                pivotS2=pivot0-(pivotR1-pivotS1);
                 return new Array(
                hi,lo,cls,pivot0,pivotR1,pivotS1,pivotR2,pivotS2);

                I'm not sure you are familiar with the syntax and how to use efsInternal(), but there are a number of links below my signature on EFS2 usage (EFS2 How-To) and several examples in my
                FileShare. If you need any help on this, please feel free to ask, I'll try to help as best I can.



                Originally posted by mike_scott
                Thankyou Short and Long for the detailed reply. I modified my efs to implement the following. I found that this will run main two times which I find curious.

                function main(parameters) {

                var nIndex = getCurrentBarIndex();
                var nState = getBarState();

                if(nState == BARSTATE_NEWBAR && nIndex == 0) {

                //Calculate pivots, support and resistance values
                etc...
                }

                I will try your example and report back. This is the most difficult script I have attempted and bar state has been confusing to me. New script attached. You will notice that I have a debug switch to change interations of the primary loop from 2 to 1 time so that I can see what was happening.

                Mike Scott
                Tarzana, CA

                Comment


                • #9
                  Re: multi-timeframe question

                  Originally posted by mike_scott

                  What did you mean my barStateAsString?

                  Mike Scott
                  Mike,

                  Sorry about that. I only posted the function barStateAsString() in the first of the three examples, even though it's used by all three. Just cut and paste it from the first example - add it sometime after main().

                  Comment


                  • #10
                    Come to think of it, although my debugPrintln works (if you've included the barStateAsString() function), it has a bug in it. close() should be close(0). Corrected:
                    PHP Code:
                        debugPrintln (barStateAsString (getBarState()) + ", bar: " getCurrentBarIndex() + ", last price: " close(0)); 

                    Comment


                    • #11
                      You might consider taking advantage of Series objects.

                      For example, your code:
                      PHP Code:
                      var QH = new Array(6);

                      QH[0] = high(nSemiIndexinv("M"));

                      QH[1] = high(nSemiIndex-1inv("M"));

                      ... 
                      Could be replaced with:
                      PHP Code:
                      var QH = new Array(6);

                      var 
                      highMonthlySeries high(inv("M"));

                      QH[0] = highMonthlySeries.getValue (nSemiIndex);

                      QH[1] = highMonthlySeries.getValue (nSemiIndex-1);

                      ... 

                      Comment


                      • #12
                        I noticed in a multi-timeframe / multi-symbol EFS study I did a while back that the first time another timeframe/symbol is used it causes all bars to be sent again. I think what happens is EFS determines it doesn't have the price data, returns null for the new timeframe/symbol, gets the price data (after main returns), then sends all bars after all the price data for the new timeframe/symbol has been received. This might explain any bizarre behavior you're seeing.

                        I'm currently working on the same thing you are: a multi- timeframe/symbol study where I only want main() to be run once.
                        I'm having the problem I mentioned above with price data being null until all bars have been sent again.

                        I'll post what I find...

                        Comment


                        • #13
                          multi-timeframe question

                          I wish to thank people for helping me with my multi-timeframe script. I have attached the script incase anyone is interested.

                          The short and long addition of returning from main() until the last bar showed up worked.

                          A couple of more questions:

                          1. These statements work when the chart is a daily interval.
                          aSR[2][3] = sma(50, sym(aSym, "D"),0); //50DMA
                          aSR[2][6] = sma(200, sym(aSym, "D"), 0); //200DMA
                          But I get 50 and 200-period averages when the chart is in different intervals. Have I written these incorrectly to always give me daily averages independent of chart interval?

                          2. This statement works okay during market hours but after the market closes I wish the "-1" to refer to the just closed market day which would be the "0" bar on the chart.
                          aSR[2][0] = (close(-1, inv("D")) + high(-1, inv("D")) + low(-1, inv("D")))/3; //Daily Pivot
                          Is there an elegant way to shift the reference after the market is closed and before the next bar begins the next day? How would I detect that the market is closed incase I need to do this the messy way.

                          Mike Scott
                          Tarzana, CA
                          ....Mike

                          Comment


                          • #14
                            mike

                            1. These look like you should get Daily on all time frames

                            2. You need to check getHour(0) and getMinute(0) to see it the time is after/before market close, then change the formulas based on the time.

                            Comment


                            • #15
                              multi-timeframe question

                              dloomis, thanks for the reply. Unfortunately I do not get daily averages unless the chart is a daily.

                              I will implement an hour and minute statements and shift the bar reference accordingly.

                              Mike Scott
                              Tarzana, CA
                              ....Mike

                              Comment

                              Working...
                              X