Announcement

Collapse
No announcement yet.

Ref: efsInternal -which of these methods is best?

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

  • Ref: efsInternal -which of these methods is best?

    I've come up with 3 ways to get plots using efsInternal() using posts found in the forum.

    Is there a way to test which is the least CPU intensive approach?

    Thanks in advance.

    PHP Code:
    //three methods of using getSeries and efsInternal
    debugClear();
    var 
    aFPArray = new Array();
    var 
    bInit false;
    function 
    preMain() {

    setPriceStudy(false);
    setStudyTitle("Donchian Strength 8c");
    setShowTitleParameterstrue );
    var 
    x=0;
        
    aFPArray[x] = new FunctionParameter"WhichMethod"FunctionParameter.STRING); 
        
    withaFPArray[x++] ) { 
            
    setName"Use Which Method" ); 
            
    addOption("getSeries in bInit"); 
            
    addOption("getSeries in return statement");
            
    addOption("getSeries using two efsInternal Functions");
            
    setDefault"getSeries in bInit" ); 
        }       
    }
    var 
    xStrengthPlot null;
    var 
    MySubStudy2 null;
    var 
    vSymbol null;
    var 
    Interval0 null;
    var 
    xMA_Avg null;

    function 
    main(WhichMethod){

        if ( 
    bInit == false ) { 
            if(
    vSymbol == null || vSymbol == ""vSymbol getSymbol();
            if(
    Interval0 == "Default" || Interval0 == nullInterval0 getInterval();
            
    xSymbol vSymbol+","+Interval0;
            if(
    WhichMethod == "getSeries in bInit"){
                
    xStrengthPlot efsInternal("Strength",xSymbol);
                if(
    xMA_Avg == nullxMA_Avg ema(34,eval(xStrengthPlot));
            }else if(
    WhichMethod == "getSeries in return statement"){
                
    //alternatively I can use the following with the corresponding "return new Array(xStrengthPlot,xMA_Avg);"
                
    xStrengthPlot getSeries(efsInternal("Strength",xSymbol),0);
                if(
    xMA_Avg == nullxMA_Avg getSeries(ema(34,eval(xStrengthPlot)));
            }else if(
    WhichMethod == "getSeries using two efsInternal Functions"){
                
    xStrengthPlot getSeries(efsInternal("DonchianStrength",xSymbol),0);
                
    xMA_Avg getSeries(efsInternal("DonchianStrength",xSymbol),1);
            }
            
    bInit true
        } 
        if(
    WhichMethod == "getSeries in bInit")
            return new Array(
    getSeries(xStrengthPlot),getSeries(xMA_Avg));
        else if(
    WhichMethod == "getSeries in return statement")
            return new Array(
    xStrengthPlot,getSeries(xMA_Avg));
        else if(
    WhichMethod == "getSeries using two efsInternal Functions"){
            
    VarDonch xStrengthPlot.getValue(0);
            
    VarMA_Avg xMA_Avg.getValue(0);
            
            return new Array(
    VarDonch,VarMA_Avg);
        }
    }


    function 
    Strength(VSymbol) {
        return (
    2*close(0,sym(VSymbol))-upperDonchian(34,sym(VSymbol))-lowerDonchian(34,sym(VSymbol)));
    }
    // function DonchianStrength(aSymbol) is used only for [WhichMethod == "getSeries using two efsInternal Functions"]
    var rStrengthPlot null;
    var 
    rMA_Avg null;

    function 
    DonchianStrength(aSymbol){
        
    rStrengthPlot efsInternal("Strength",aSymbol);
        if(
    rMA_Avg == nullrMA_Avg ema(34,eval(rStrengthPlot));
        return new Array(
    rStrengthPlot,rMA_Avg.getValue(0));

    Last edited by waynecd; 11-21-2008, 08:28 PM.

  • #2
    Re: Ref: efsInternal -which of these methods is best?

    Hi Waynecd,

    Use the performance monitor to test the differences in speed. Check this thread for a discussion on the performance monitor.

    As for using efsInternal (or any method of creating a series object), there are several tips.

    1) Only create the series once (regardless of where it is used).
    2) For functions that are being used with efsInternal that have their own embedded series objects, return the existing series object if that is what you want.
    3) Use the series object method getValue() to access the values from existing series objects.


    Hope this helps.

    Originally posted by waynecd
    I've come up with 3 ways to get plots using efsInternal() using posts found in the forum.

    Is there a way to test which is the least CPU intensive approach?

    Thanks in advance.


    Comment


    • #3
      Hi Steve,

      Thanks again. It helps alot.

      I had your reference post but lost it in my filing system, can't let that happen.

      Wayne

      Comment


      • #4
        Hi Waynecd,

        Your most welcome. Good to hear the info was helpful. FWIW, an addendum to my last post.

        4) getSeries() returns a series and like all other methods or functions that return a series object, it only needs to be called once.

        ... and a clarification...

        Create series objects in a bInit conditional or an allbars conditional. Assign global variables to the series objects to maintain access to them for the life of the efs. (The global variables act as pointers to the series objects.) Use the global variables to refer to the existing series. This minimizes resource use as compared to repeatedly using getSeries() and maximizes efs efficiency.

        Comment


        • #5
          Hi Steve,

          Thanks for the clarification and addendum. I really appreciate it.
          Very timely for what I am doing now.

          Wayne

          Comment


          • #6
            Hi Wayne,

            You are most welcome. In hindsight I noticed getSeries() had not been addressed.

            Hope this works out for you. Let me know if you have any followup questions.

            Comment


            • #7
              Hi Steve,

              I appreciate your help.

              To make sure I understand: below is a comparison of two return statements one using the getSeries() and the other just calling the last value in the original series created by the stoch?() functions. As I understand it now, it is better to call the last value via stoch?.getValue(0) (doesn't create a new series) instead of getSeries(stoch?) which creates a new series.

              Is this correct?

              PHP Code:
              var bInit false;
              var 
              xStochK null;
              var 
              xStochD null;

              function 
              main(Symbol,Interval) {

                  if(
              bInit == false){
                      if(
              Symbol == nullSymbol getSymbol();
                      if(
              Interval == nullInterval getInterval();
                      var 
              vSymbol Symbol+","+Interval;
                      
              xStochK stochK(14,1,3,sym(vSymbol));
                      
              xStochD stochD(14,1,3,sym(vSymbol));
                      
              addBand80PS_SOLID1Color.black,"Upper");
                      
              addBand20PS_SOLID1Color.black,"Lower");
                      
              bInit true;
                  }

              //    return new Array (getSeries(xStochK),getSeries(xStochD));
                  
              return new Array (xStochK.getValue(0),xStochD.getValue(0));

              Last edited by waynecd; 11-26-2008, 07:44 AM.

              Comment


              • #8
                Hi Wayne,

                You are most welcome. Good followup. As to your questions, there are some subtleties in the implementation that can be improved on.



                Originally posted by waynecd
                Hi Steve,

                I appreciate your help.

                To make sure I understand: below is a comparison of two return statements one using the getSeries() and the other just calling the last value in the original series created by the stoch?() functions.
                First, using getSeries() as you have it structured with existing series objects is not appropriate. The best way to return an existing series to the chart is by just returning the series object.

                1) Using getSeries() - return new Array (getSeries(xStochK),getSeries(xStochD)); // Calls the getSeries() function twice, each returning a series object that will be returned to the chart as part of an array

                2) More efficient - return new Array (xStochK.getValue(0),xStochD.getValue(0)); // Calls the getValue() Methods (twice) of each series object and returns numerical values to the chart as part of an array.

                3) Most efficient - return new Array (xStochK,xStochD); // Calls no functions or methods, simply returns two series objects to chart as part of an array

                The first two each call a function or method twice every tick. The third does not call any functions and because of that, is more efficient than the first two.

                If on the other hand you had declared two local variables in the efs,

                var sK=xStochK.getValue(0);
                var sD=xStochD.getValue(0);

                2a) return new Array (sK,sD); // returns numerical values to the chart as part of an array.

                3a) return new Array (xStochK,xStochD); // Calls no functions or methods, simply returns two series objects to chart as part of an array

                These two will be more evenly matched with regards to efficiency. Understand that returning a series object to the chart has significant advantages when its interval is different than the charts.


                As I understand it now, it is better to call the last value via stoch?.getValue(0) (doesn't create a new series) instead of getSeries(stoch?) which creates a new series.

                Is this correct?

                As discussed above, both techniques call methods or functions which can be an unecessary resource expenditure. However, in your example, the use of getSeries() is not appropriate since both series are already defined. The use of getSeries() was intended to return a distinct series object when an efs2 efsInternal() or efsExternal() Object is created and the efs2 Object has multiple return values/series (i.e. return new Array(first,second,third))

                If the efs2 Object only has one returned series, the efs2 Object simply represents a single series. If the efs2 Object consists of three series, use the getSeries() function to extract each of the three series.

                Only use getSeries() when extracting individual series from an efs2 Object that is constructed from several series objects. Only use getSeries once to obtain the series you want. You only will introduce inefficiencies into your code when you use getSeries() more than you have to.

                Hope this helps.

                Comment


                • #9
                  Hi Steve,

                  Thanks so much for the detailed explanation. For me, it's not too intuitive. I think I need to study object oriented programming.

                  Again thanks.

                  Wayne

                  Comment


                  • #10
                    Hi Steve,

                    Working through the examples the only one that doesn't plot is the:

                    return new Array (xStochK,xStochD);

                    I must be missing something.

                    PHP Code:
                    var bInit false;
                    var 
                    xStochK null;
                    var 
                    xStochD null;

                    function 
                    main(Symbol,Interval) {

                        if(
                    bInit == false){
                            if(
                    Symbol == nullSymbol getSymbol();
                            if(
                    Interval == nullInterval getInterval();
                            var 
                    vSymbol Symbol+","+Interval;
                            
                    xStochK stochK(14,1,3,sym(vSymbol));
                            
                    xStochD stochD(14,1,3,sym(vSymbol));
                            
                    addBand80PS_SOLID1Color.black,"Upper");
                            
                    addBand20PS_SOLID1Color.black,"Lower");
                            
                    bInit true;
                        }
                    //var sK=xStochK.getValue(0);
                    //var sD=xStochD.getValue(0);

                    //    return new Array (getSeries(xStochK),getSeries(xStochD));//inefficient
                    //    return new Array (xStochK.getValue(0),xStochD.getValue(0));//inefficient
                        
                    return new Array (xStochK,xStochD);//doesn't plot
                    //    return new Array (sK,sD);//works

                    Thanks,

                    Wayne

                    Comment


                    • #11
                      Hi Wayne,

                      I contradicted the Knowledgebase documentation a bit with regards to the getSeries() function, sorry about that. The getSeries() function can be called repeatedly. However, for your example, the following should correct things.

                      Modify / add the following lines in your bInit statement:


                      xStochK = stochK(14,1,3,sym(vSymbol));
                      xStochK=getSeries(xStochK);

                      xStochD = stochD(14,1,3,sym(vSymbol));
                      xStochD=getSeries(xStochD);


                      For the reasons mentioned before this should improve performance.

                      After doing performance testing, please provide some feedback on how the different versions perform.

                      Comment


                      • #12
                        Hi Steve,

                        As far as I can tell they are all equivalent since the total calls vary depending on how many calls squeeze through before I can change the option parameter.

                        Wayne


                        PHP Code:
                        /*
                                        Total Calls    Total Time (ms)            Avg Time(ms)
                        Option A        318                    10                    0.03145
                        Option A        319                    10                    0.03135
                        Option B        323                    10                    0.03049
                        Option B        319                    10                    0.03115
                        Option C        319                    10                    0.03096
                        Option C        319                    10                    0.03115
                        Option D        325                    10                    0.03106
                        Option D        325                    10                    0.0304

                        */

                        debugClear();
                        var 
                        aFPArray = new Array();

                        function 
                        preMain() {

                        setPriceStudy(false);
                        setStudyTitle("Donchian Strength Color");

                        var 
                        x=0;
                            
                        aFPArray[x] = new FunctionParameter"ReturnStatement"FunctionParameter.STRING); 
                            
                        withaFPArray[x++] ) { 
                                
                        setName"Return Statement" ); 
                                
                        addOption"A" ); 
                                
                        addOption"B" ); 
                                
                        addOption"C" ); 
                                
                        addOption"D" ); 
                                
                        setDefault"D" ); 
                            }       
                        }
                        var 
                        bInit false;
                        var 
                        xStochK null;
                        var 
                        xStochD null;

                        function 
                        main(Symbol,Interval,ReturnStatement) {

                            if(
                        bInit == false){
                                if(
                        Symbol == nullSymbol getSymbol();
                                if(
                        Interval == nullInterval getInterval();
                                var 
                        vSymbol Symbol+","+Interval;
                                
                        xStochK stochK(14,1,3,sym(vSymbol));
                                
                        xStochD stochD(14,1,3,sym(vSymbol));
                                if(
                        ReturnStatement == "D") {
                                    
                        xStochK=getSeries(xStochK);
                                    
                        xStochD=getSeries(xStochD); 
                                }
                                
                        addBand80PS_SOLID1Color.black,"Upper");
                                
                        addBand20PS_SOLID1Color.black,"Lower");
                                
                        bInit true;
                            }
                            if(
                        ReturnStatement == "C") {
                                var 
                        sK=xStochK.getValue(0);
                                var 
                        sD=xStochD.getValue(0);
                            }
                            
                            if(
                        ReturnStatement "A") return new Array (getSeries(xStochK),getSeries(xStochD));//inefficient
                            
                        if(ReturnStatement "B") return new Array (xStochK.getValue(0),xStochD.getValue(0));//inefficient
                            
                        if(ReturnStatement "C") return new Array (sK,sD);//works
                            
                        if(ReturnStatement "D") return new Array (xStochK,xStochD);//works

                        Last edited by waynecd; 11-27-2008, 09:53 PM.

                        Comment


                        • #13
                          Hi Wayne,

                          It looks like you just measured historical data load performance. To get a better measure of performance, run tick playback data for 2 or three days (accelerated of course). Additionally, remove all the if statements and just comment the ones you do not use. They will mask differences.
                          Last edited by ; 11-28-2008, 08:49 AM.

                          Comment


                          • #14
                            hi Steve,

                            Ah, I see said the blind man, that was a useless test.

                            I think I got it right this time. Attached is a zip file with code for each option and a jpg of the EFS Performance Monitor.

                            Data is for a 3 day Tick Replay with 55T data and chart.

                            As you commented in your previous post, Option D (see code below) is the most efficient:

                            PHP Code:
                            /*Best overall score
                            Option    Total Calls   Total Time    Avg Time
                            A       841184            23234        0.02762
                            B       841184            5036        0.005987
                            C        841184            5389        0.006406
                            D        841184            3623        0.004307
                            E        841185            7102        0.008443
                            */
                            function preMain() {

                            setPriceStudy(false);
                            setStudyTitle("Stochs Efficiency TestD");

                            }
                            var 
                            bInit false;
                            var 
                            xStochK null;
                            var 
                            xStochD null;

                            function 
                            main(Symbol,Interval,ReturnStatement) {

                                if(
                            bInit == false){
                                    if(
                            Symbol == nullSymbol getSymbol();
                                    if(
                            Interval == nullInterval getInterval();
                                    var 
                            vSymbol Symbol+","+Interval;
                                    
                            xStochK stochK(14,1,3,sym(vSymbol));
                                    
                            xStochD stochD(14,1,3,sym(vSymbol));
                                    
                            xStochK=getSeries(xStochK);
                                    
                            xStochD=getSeries(xStochD); 
                                    
                            addBand80PS_SOLID1Color.black,"Upper");
                                    
                            addBand20PS_SOLID1Color.black,"Lower");
                                    
                            bInit true;
                                }
                                
                                return new Array (
                            xStochK,xStochD);

                            Attached Files
                            Last edited by waynecd; 11-28-2008, 01:11 PM.

                            Comment


                            • #15
                              Hi Steve,

                              Just wondered if you still have comments on the items below?
                              Either way, thanks for your help.

                              Wayne

                              (1)correction regarding my earlier comment on the getSeries() function and
                              (2) discusssion of previous issues with the performance monitor and efs2.
                              (3) a followup from you on item 2 which requires some additional testing on your part...

                              Comment

                              Working...
                              X