Announcement

Collapse
No announcement yet.

Getting a series of two series via efsInternal

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

  • Getting a series of two series via efsInternal

    I'd like to get a function of multiple series and the function's output as a series as well. So I thought I'd achieve that via efsInternal. But EFS gets hung on the following code:

    var s1 = sma(10);
    var s2 = sma(50);
    var dS = null;
    var bInit = false;

    function preMain () {

    ... usual stuff ...

    }

    function main() {
    if (getBarState() == BARSTATE_ALLBARS) return;

    if (bInit == false) {
    bInit=true;
    if (dS==null) dS=efsInternal("calc_f");
    }

    var dSs = getSeries(dS, 0);

    // then do something with dSs

    }

    function calc_f() {

    return (getSeries(s1) -getSeries(s2));
    }

    I am sure I am misunderstanding something here about getSeries()...

    any help would be greatly appreciated.

    ziggy

  • #2
    Hi z11,

    Your construct is wrong. Please look at the links I copied from the EFS2 links I keep signature. Alex has put together a fairly comprehensive set of examples. This should help you on this.

    http://forum.esignalcentral.com/show...2682#post82682

    http://forum.esignalcentral.com/show...threadid=12752

    http://forum.esignalcentral.com/show...threadid=12924

    http://forum.esignalcentral.com/show...6586#post76586

    Comment


    • #3
      Thanks for the links, Steve.
      I actually have book-marked all these since they first appear and I re-read them ...I think my problem is :

      return (getSeries(s1) - getSeries(s2));

      in calc_f

      ...if I do:

      return (getSeries(s1).getValue(0) - getSeries(s2).getValue(0));

      would that accomplish my objective of having dSs as a series object which I in turn can pass it to other functions and/or efsInternals as a series object...? Is that what you mean by my construct is wrong?

      Thanks again...

      ziggy

      Comment


      • #4
        Hi Ziggy,

        Ok, I think I see. Your example was a bit abbreviated and because of that, things were not clear and a bit off from here. Your second post is a bit closer though.

        Back to the first post though... assuming you have the formatting down correctly, subtracting two series from each other does not work.

        Regarding a series, it may help to think of a series as an object with significantly more data in there than just the bar data, unless there is a method associated with the series object that was built specifically for that purpose, it would not work (plus it would be very inefficient).

        If I remember correctly, trying to create a series object (s1 and s2) and setting them equal to an efs2 function outside main and premain is not correct. I do not believe the series associated with price is available until you are within the main() function, so both s1 and s2 will always be null the way you seem to have set things up.

        What you should do is create an efsInternal function that declares both of the moving average series and subtracts the numbers from each other in the function and include this value in the return statement.

        Now this is a bit abbreviated (note that s1 is not global but needs to be, plus the bInit test and closure are incorrect and the bInit is not a global variable...)

        function calc_f() {
        var s1 = sma(10);
        var s2 = sma(50);
        var dS = null;
        var bInit = false;

        return (s1.getValue(0) - s2.getValue(0));
        }


        As to your second post, I am not sure your use of getSeries() is quite right. While it would work if you had the internal function set up correctly, it is probably not the most efficient use of the tool.

        If I remember correctly, the purpose of getSeries() was to allow you to return a series to a chart that was of a longer timeframe than the chart. This would update the chart for the entire duration of the longer interval, ensuring that the chart that was drawn in real time was identical to the historical chart (if you were to reload it, the chart would look the same).

        Comment


        • #5
          Hi Ziggy,

          I am not sure if you were able to figure this out, so I went ahead and wrote an efs in an attempt to better explain my thoughts. I use the same function and use it in the creation of two efsInternal() objects. The first one is assigned to global variable 'dS' and it is using the timeframe of your chart. The second one is 'dS10' and it is calculated at a 10 minute interval.

          Both of these return a series to the chart, but they are handled differently to demonstrate the difference between getSeries() and getValue(). To see this difference, try running this efs on a 1 minute chart.

          I hope this helps.



          PHP Code:
          /* Notes:
          Study requires version 8.0 or later.
          X11 MA-MA -  S. Hare - 2 5 2007, Version 1.0

          [url]http://share.esignal.com/fileupload.jsp?groupid=339&folder=EFS2%20MA[/url]
          */

          var bInit false// these are global variables, they can be seen in every part of the efs
          var s1;
          var 
          s1;
          var 
          dS;
          var 
          dS10;

          var 
          fpArray = new Array();

          function 
          preMain() {
           
          setPriceStudy(false);
           
          setStudyTitle("MA-MA");
           
          setCursorLabelName("MA-MA",0);
           
          setDefaultBarFgColor(Color.blue,0);
           
          setDefaultBarThickness(2,2);
           
          setCursorLabelName("MA10-MA10",1);
           
          setDefaultBarFgColor(Color.red,1);
           
          setDefaultBarThickness(2,1);
           
          InitFunctionParameter();
          }

          function 
          main(MA1MA2) {
           if(
          bInit == false){
            
          dS efsInternal("calc_f"MA1MA2close());
            
          dS10 efsInternal("calc_f"MA1MA2close(inv("10")));
            
          bInit true;
           }
           

           if(
          nullFlag){
            if(
          dS.getValue(0) != null && dS10.getValue(0) != null)
            {
             
          nullFlag false;
            }
            else return;
           }
           var 
          dSs dS.getValue(0);

           
          // then do something with dSs

           
          return new Array(getSeries(dS10),dSs);
          }

          var 
          nullFlag true;
           
          function 
          calc_f(MA1MA2,source)
          {
           
          // note that this function uses four global values that also used in the main efs
           // bInit, nullFlag, s1 and s2
           // if this function were called as a regular function from main, these would typically change in this function when they changed 
           // in main.  They would be shared global variables.  However, this function is used in the creation of an efsInternal() object.  This
           // opens this function as a separate object/entity outside the context of the main efs.  As a result, while 
           // this efs has access to the global variables as they are initially set, once declared in this manner, the variables are not shared whatsoever.  In fact,
           // the only communications path is through the return statement of this efsInternal Object's return statement.
           
           
          if(bInit == false){
            
          s1 sma(MA1,source);
            
          s2 sma(MA2,source);  
            
          bInit true// this starts out as a global value set to false, but since this function is used in the creation
           
          }             //  of an efsInternal() object, this 'bInit' is distinct from other instance in main
           
           
          if(nullFlag){
            if(
          s1.getValue(0) != null && s2.getValue(0) != null)
            {
             
          nullFlag false;
            }
            else return;
           }
           return (
          s1.getValue(0) -s2.getValue(0));
          }

          // now the customizable user inputs 
          function InitFunctionParameter()
          {
           var 
          0;
           
          fpArray[x] = new FunctionParameter("MA1"FunctionParameter.NUMBER);
           
          with(fpArray[x++])
           {
            
          setName("Length");
            
          setLowerLimit(2);
            
          setDefault(10);
           }
           
          fpArray[x] = new FunctionParameter("MA2"FunctionParameter.NUMBER);
           
          with(fpArray[x++])
           {
            
          setName("Length");
            
          setLowerLimit(2);
            
          setDefault(50);
           }


          Attached Files

          Comment


          • #6
            Hello Steve,

            Thanks for the (usual) detailed work.
            After our last exchange, I tried out last night the original code with return (s1.getValue(0) - s2.getValue(0)) in the efsInternal function and it worked for the first call to the internal function...I actually called the internal function multiple times with different MA1 MA2 pairings ... only the first call succeeded ... none of debug statements in subsequent calls showed up ... I will post my code later tonight(it's on a different PC.)

            Thanks again.

            ziggy

            Comment


            • #7
              Hi Ziggy,

              You are most welcome. I am sure the work you did last night will help. I can tell you from experience (as recent as last night in fact) that when there is an error in a function that is part of an efsInternal() object, any debugPrintln() statements in the function will typically not work. (FWIW, I have come to use this as an early warning that there is something not quite right.)

              I am sure it is something minor keeping your efs from full functionality. Working through issues like this is helpful to us all. I will be around later tonight, let me know how things are going.

              Comment


              • #8
                This is the code I have been experimenting with:

                //Global Variables
                var ma1 = sma(5);
                var ma2 = sma(10);
                var ma3 = sma(40);
                var dma1 = null;
                var dma2 = null;
                var dma3 = null;
                var adma1 = null;
                var adma2 = null;
                var adma3 = null;

                var nBarcount = 0;
                var bInitialized = false;

                function preMain() {
                var x;

                setPriceStudy(false);
                setStudyTitle("maDiff");
                setCursorLabelName("m5m10", 0);
                setCursorLabelName("m10m40", 1);
                setCursorLabelName("m5m40", 2);
                setDefaultBarFgColor( Color.red, 0 );
                setDefaultBarFgColor( Color.blue, 1 );
                setDefaultBarFgColor( Color.black, 2 );
                setDefaultBarThickness( 2, 0);
                setDefaultBarThickness( 2, 1);
                setDefaultBarThickness( 2, 2);

                }

                function main() {
                var x;
                var nRet1, nRet2, nRet3;
                var nPlot1, nPlot2, nPlot3;

                if (getBarState() == BARSTATE_ALLBARS) {
                return null;
                }

                if (bInitialized==false) {
                bInitialized = true;
                debugPrintln("init b> dma1");
                if (dma1 == null) dma1 = efsInternal("calc_dma1");
                debugPrintln("init b> dma2");

                if (dma2 == null) dma2 = efsInternal("calc_dma2");
                debugPrintln("init dma3");
                if (dma3 == null) dma3 = efsInternal("calc_dma3");

                if (adma1 == null) adma1 = efsInternal("calc_adma1");
                if (adma2 == null) adma2 = efsInternal("calc_adma2");
                if (adma3 == null) adma3 = efsInternal("calc_adma3");
                }

                nBarcount++;
                debugPrintln("before getSeries");

                var d1S = getSeries(dma1, 0);
                var d2S = getSeries(dma2, 0);
                var d3S = getSeries(dma3, 0);

                return new Array(d1S.getValue(0),d2S.getValue(0),d3S.getValue (0));
                // return new Array(d1,d2,d3);
                // return new Array(getSeries(dma1),getSeries(dma2),getSeries(dm a3));
                }


                function calc_dma1() {
                debugPrintln("in calc_dma1 > "+ getCurrentBarIndex());

                //debugPrintln(ma1.getValue(0) - ma2.getValue(0));

                return new Array(ma1.getValue(0) - ma2.getValue(0));
                return (ma1 - ma2);
                }

                function calc_dma2() {
                debugPrintln("in calc_dma2");
                return (ma2.getValue(0) - ma3.getValue(0));
                // return (ma2 - ma3);

                }

                function calc_dma3() {
                debugPrintln("in calc_dma3");
                return (ma1.getValue(0) - ma3.getValue(0));
                // return (ma1 - ma3);

                }

                function calc_adma1() {
                return(abs(dma1.getValue(0)));
                }

                function calc_adma2() {
                return(abs(dma2.getValue(0)));

                }

                function calc_adma3() {
                return(abs(dma3.getValue(0)));

                }

                ...still trying to figure out what's wrong here...

                ziggy

                Comment


                • #9
                  ziggy
                  The issue you are having is caused by the fact that bInit = true; is being executed prior to the efsInternal() calls whereas it needs to be executed after.
                  This post by Dion Loy explains how an efs executes when it calls an efsInternal() or efsExternal() function (or an external symbol/interval) and consequently why bInit = true needs to be placed after those calls have been executed
                  Alex

                  Comment


                  • #10
                    wow, incredible .. .all these years I have by pure chance always had bInit as the last line in the bInit == false clause ...except with this little experiment ... thanks for the insight....boy wonder what else I might wrong somewhere...
                    (... this is the time fans in the stadium would be bowing to you in waves as show of appreciation and your awesome display of deep knowledge...)

                    Thanks Alex,

                    ziggy

                    P.S. ... I still can't figure out why the tick replay would not work on one PC with dual-core... maybe there is something else I missed...

                    Comment


                    • #11
                      ziggy
                      You are most welcome and thank you for the kind words
                      Alex

                      Comment

                      Working...
                      X