Announcement

Collapse
No announcement yet.

efsExternal(inv(?)) usage with ordinary script

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

  • efsExternal(inv(?)) usage with ordinary script

    I kindly ask Alex Montenegro to answer this, or someone at eSignal with similar knowledge of EFS internals.

    I have a script that has no knowledge of what interval and symbol it is running with. And I would like to keep it that way. For example:

    file coolIndicator.efs:
    PHP Code:
    function main()
    {
        if (
    getCurrentBarIndex() % == 0)
            return 
    open(0);
        else 
            return 
    close(0);

    (the actual indicator is more complex, but I wanted to convey that:
    a) it does not use any sym() or inv()
    b) it does use getCurrentBarIndex() to track how many bars ago certain events have occurred.

    The EFS Help page for efsExternal() says the following (only):

    efsExternal( pathToEFS [, sym/inv] [, parameters] )

    New in EFS2. Returns a series object representing the values as calculated from the given external EFS script. You would then use the getSeries() function to extract a specific series value if multiple series are returned.

    The help page further gives an example:

    PHP Code:
    //call an external EFS called "myCustomEFS.efs" and load it into
       //the context of IBM 15-min bars. we also pass two parameters
       //to the script.
       
    myVar efsExternal"myCustomEFS.efs"sym"IBM,15" ), 20); 
    Note that nothing is said regarding the support that myCustomEFS.efs must have for the external interval. It makes an impression that any simple script alike coolIndicator.efs, as mentioned above, would just be executed on IBM 15 min bars, without having to modify the called script to support multiple intervals/symbols.

    I think I am finding out that it is not really true. The truth is, as Alex described
    here and here that every EFS has to be retrofitted to work with multiple intervals.

    In other words,
    PHP Code:
    efsExternal("blah.efs"inv(10)) 
    will only work when the main() function of blah.efs accepts Symbol and Interval parameters and uses it to call sym().

    However, if EFS is modified in that way, it can no longer rely on getCurrentBarIndex() because this function always returns the index of the bar on the current chart and not that of the external timeframe.

    Now, the BIG QUESTION:

    Alex - or somebody who can answer this - would you be so kind to tell me whether my understanding of the situation is right or wrong?

    If it is right - why would you not consider updating the EFS Help page for efsExternal() to avoid confusion. If wrong - can you give me an example of calling my script coolIndicator.efs (above) from another timeframe, without having to modify the code of the indicator (and so that getCurrentIndex() would work as it would natively).

    I hope my question is not too convoluted.

    Many thanks
    pupkin2

  • #2
    Hi pupkin2,

    Your question is somewhat convoluted insomuch that it starts with a misconception and builds on that misconception. Specifically, when using efsExternal, neither the symbol or interval need to be provided if you want the efs to run on the same interval and symbol as the efs invoking the external efs. What you may be missing is that you must provide those parameters in the function main(a,b,c,d,e) of the efs being called.

    Some clarifications that may help. Please consider the following examples to see if they are of assistance.

    consider the following efs, titled "simple ma.efs"

    PHP Code:
    var nMA;var bInit false;
    function 
    main(Symbol,Interval) {
     if(
    bInit == false){
      
    debugPrintln("Symbol = "+Symbol);
      if(
    Symbol == nullSymbol getSymbol();
      if(
    Interval == nullInterval getInterval();
      var 
    vSymbol Symbol+","+Interval;
      
    nMA sma(10,close(sym(vSymbol)));
      
    bInit true;
     }
     return 
    getSeries(nMA);

    I would like you to run the following three efs's, where each one calls the external efs in a different manner. Open up an advanced chart and set the interval to 1 minute.

    Here is one method in which to invoke the external efs:

    myVar = efsExternal( "simple ma.efs", "IBM",3, inv( "5" ))

    You are invoking the external efs to run in a 5 minute timeframe, but you will then tell it to use "IBM" as the symbol and use a 3 minute timeframe for the moving average. Not the most sensical way of running things, but it still works.

    PHP Code:
    var bInit false;
    var 
    xMA null;
    var 
    myVar null;
    function 
    main() {
     if(
    bInit == false){
      
    myVar efsExternal"simple ma.efs""IBM",3inv"5" ));
      
    bInit true;
     }
     return 
    getSeries(myVar);



    Now, try this method in which to invoke the external efs where you replace the symbol and iterval with null.
    myVar = efsExternal( "simple ma.efs",null,null, inv( "5" ))

    Since the invoked efs tests for null and provides the interval and symbol information, it will see the null input for the symbol and interval and populate that information. You will be running the efs in a 5 minute timeframe and the null check will see that you are running in that timeframe, assigning the interval to "5".


    PHP Code:
    var bInit false;
    var 
    xMA null;
    var 
    myVar null;
    function 
    main() {
     if(
    bInit == false){
      
    myVar efsExternal"simple ma.efs"nullnullinv"5" ));
      
    bInit true;
     }
     return 
    getSeries(myVar);


    If however, you try this method of invoking the the external efs, it will not work as it expects you to provide the two inputs.

    myVar = efsExternal( "simple ma.efs", inv( "5" ))


    PHP Code:
    var bInit false;
    var 
    xMA null;
    var 
    myVar null;
    function 
    main() {
     if(
    bInit == false){
      
    myVar efsExternal"simple ma.efs"inv"5" ));
      
    bInit true;
     }
     return 
    getSeries(myVar);

    Comment


    • #3
      Dear stevehare2003,

      Thanks for your info.

      The misconception about efsExternal() is caused by the EFS Help page, which I quoted in my last post. The example there makes me believe that any EFS can be run in an interval or symbol+interval specified via the second parameter to the efsExternal() call - regardless of the implementation of the EFS that is being called. This is because that Help page says nothing regarding the fact that the sym() or inv() parameter it passes to the EFS must actually be a parameter of the main() method of the called EFS.

      I seem to share this misconception with some other eSignal/EFS users that I talked to. As we know, any script written for a single-timeframe (one that does not enforce its own Symbol and Interval or does not take them as arguments) can be placed on a eSignal Advanced Chart and will work in the timeframe and symbol of that chart. Right? Well, basically, after reading that EFS Help page it seemed that efsExternal() does exactly that - it "places" an arbitrary script onto a "virtual" chart, as specified by the sym() parameter.

      Okay, I do not have that misconception anymore - you've explained that it is not the case, and so did Alexis in his posts.


      But I do still have a question regarding getCurrentBarIndex(). Suppose, I wrote a script that uses getCurrentBarIndex() - and how I'm having to adapt this script to multi-timeframe mode (by adding Symbol and Interval arguments to its main()) - I think the problem is that getCurrentBarIndex() returns the bar number in the current chart's timeframe, and not in any external timeframe - how can I use it then?

      Example:
      PHP Code:
      var maCrossBarNumber null;

      function 
      main()
      {
          if(
      ma(5) > ma(10))
          {
              
      maCrossBarNumber getCurrentBarIndex();
          }
          else if(
      getCurrentBarIndex() - maCrossBarNumber <= 10 )
          {
              
      // MAs crossed within last 10 bars  - add more code here
          
      }


      Of course, the second alternative is less performant, it would be to have a for() loop to search backwards for 10 bars for the crossing - and do so every time main() is invoked.

      My question here is - I do not like this second alternative, can I do something to be able to use getCurrentBarIndex() so that it would return the bar number of the external timeframe that I'm working with (passed to me by Symbol and Interval) ?

      Thanks

      Comment


      • #4
        pupkin2,

        You are still a bit off with regards to the external interval. If you take a look at the examples, the primary controlling interval is what you are including in your efsExternal() invocation. Here is another set of examples.

        Here is the modified efs, titled "simple ma.efs"

        PHP Code:
        var nMA;var bInit false;
        function 
        main() {
         if(
        bInit == false){
          
        nMA sma(10,close());
          
        bInit true;
         }
         return 
        getSeries(nMA);


        Now, here in the first example, the efs which is using the efsExternal() invocation is controlling the interval of the external efs.

        PHP Code:
        var bInit false;
        var 
        xMA null;
        var 
        myVar null;
        function 
        main() {
         if(
        bInit == false){
          
        myVar efsExternal"simple ma.efs"inv"5" ));
          
        bInit true;
         }
         return 
        getSeries(myVar);

        Now, here in the second example, the efs which is using the efsExternal() invocation is still controlling the interval of the external efs even though it is not sending an interval command. The interval that is being used is simply the interval of the efs containing the efsExternal() invocation.

        PHP Code:
        var bInit false;
        var 
        xMA null;
        var 
        myVar null;
        function 
        main() {
         if(
        bInit == false){
          
        myVar efsExternal"simple ma.efs");
          
        bInit true;
         }
         return 
        getSeries(myVar);

        If you take a look at my previous post this is pretty consistent with the information there. I learned these techniques btw by using the EFS help page and looking at the numerous examples on the forum, which I believe are very informative. As far as the the other eSignal/EFS users that you referred to, I would encourage them to carefully look at the numerous examples on the forum as well.

        Regarding the use of getCurrentBarIndex(), once efs has processed all of the historical bars, the value returned will be either (-1) or (0), depending on whether you have set the efs to computeOnClose or not. Here is the section from the help file on bar index, you will see that it is referred to as the offset from the current bar.






        Based on how you are seemingly trying to use it, it appears what you may be looking for is the bar count, which can be obtained using getCurrentBarCount(). You cannot get the barcount of an external interval, but you can keep track of new bars on an external interval with this other command. Here is a copy of that section from the help file as well.





        In all cases, there are numerous examples on the forum on how to use these commands, should you, or your associates need additional information on them.
        Last edited by ; 03-28-2006, 04:45 AM.

        Comment


        • #5
          pupkin2

          The example there makes me believe that any EFS can be run in an interval or symbol+interval specified via the second parameter to the efsExternal() call - regardless of the implementation of the EFS that is being called. This is because that Help page says nothing regarding the fact that the sym() or inv() parameter it passes to the EFS must actually be a parameter of the main() method of the called EFS.
          Actually you do not necessarily have to include the parameter in the main() definition of the called efs [if only sym() or inv() are being passed to it] and I don't believe I have stated otherwise in either of the threads you point to in your first post in this thread. As a matter of fact on more than one occasion (see here for a recent example) I have indicated that you can control the context in which the called efs is run by simply adding sym() or inv() as the last parameter of the efsInternal() or efsExternal() functions. At the same time I have also suggested that it is good coding practice to include the parameter in the main definition of the called efs.
          The reason the parameter is included in most of my examples is because I usually nest the sym() or inv() series in a data series.
          That said you may want to read this post with regards to the current requirement for passing sym() or inv() in efsExternal().
          It is my understanding that the documentation does not intentionally specify this requirement because it will be removed in one of the next releases of the software ie you will be able to pass sym() or inv() as the sole parameter other than the name of the called efs [for example efsExternal("myEFS.efs", inv(interval))]
          Alex

          Comment


          • #6
            Alex and Steve,

            Thank you both for your replies. Alex, the second link in your post that solves member z11's trouble - that is exactly the trouble I was having, too.

            That would actually also be the trouble with the first example in Steve's most recent post here, in invoking
            PHP Code:
            efsExternal("simple ma.efs"inv(5)) 
            If you call it as in the line above, and then display the caller-EFS in an adv. chart, you will get something like the one attached (sorry, I'm new to this board, and don't know how to inline images within text). Note that the chart was for 1-minute interval, but the study on the chart has a new value for each bar - this indicates that inv(5) parameter did not work.

            The reason why it did not work is because, according to Alex's example for z11, it had to be called as
            PHP Code:
            efsExternal("simple ma.efs"0inv(5)) 
            . This means that, although the main() function of "simple ma.efs" does not have any arguments, it implicitly expects one argument (the "0" before the inv(5) - I'm guessing this must be the Length parameter that I saw in some examples).

            I'm sure there are explanations for this, scattered around this bulletin board, but I wish that the EFS Help reference/guide were a bit more clear on what exact arguments main() has passed to it. I could not find an EFS Help page that would say that even when main() was declared without any arguments, it will still be implicitly (by the EFS engine) re-declared as having one argument, Length (?).

            I'm coming from Java and C++ programing background (and some non-EFS JavaScript as well) and it is difficult for me to get, because it is unusual/unexpected.
            Attached Files
            Last edited by pupkin2; 03-28-2006, 02:38 PM.

            Comment


            • #7
              pupkin2

              This means that, although the main() function of "simple ma.efs" does not have any arguments, it implicitly expects one argument (the "0" before the inv(5) - I'm guessing this must be the Length parameter that I saw in some examples).
              That first parameter is actually a remnant of the efs() function - which has been superceeded by efsExternal() - and was required to retrieve a specific element in the return of the called efs [because unlike efsExternal() the efs() function could not retrieve an array]. For more information on the efs() function see this thread.
              As I said in my prior reply this extra parameter will no longer be required in one of the next releases of the software.
              Alex

              Comment

              Working...
              X