Announcement

Collapse
No announcement yet.

Questions on efslib

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Questions on efslib

    It apppears that one can have global (external) varaibles in an efslib. What are the scope of these global variables? If I am running two charts and both charts use an indicator that calls function(s )within the same efslib. Does each chart get it's own set of global variables? Or do both charts see (use) the same global variables?

    I am assuming that any variables decalred within a function in a esflib are local in nature and therefore there values are destroyed when the function is exited.

    What is the scope of an efslib?

  • #2
    scjohn,

    If I am running two charts and both charts use an indicator that calls function(s )within the same efslib. Does each chart get it's own set of global variables? Or do both charts see (use) the same global variables?
    It is just like each efs has the function. Each efs that uses "addLibrary" to add the library instantiates a separate instance of the function. Those variables declared globally to the functions within a library are just like you declared them as global variables within the efs. They are not shared between the efs's.

    I am assuming that any variables decalred within a function in a esflib are local in nature and therefore there values are destroyed when the function is exited.
    Yes, those variables declared within a function in the library are local to the function.

    Comment


    • #3
      So, if I have ca chart with 8 indicators on it and all 8 indicators use the same efslib, then I would have 8 copies of the efslib. Sound like an awful lot of overhead.

      Comment


      • #4
        scjohn,

        Overhead is relative. For example, if you are using a function from a library that involves extensive recursion, that by itself would potentially result in significant resource allocation. Using that same function 8 times would involve an awful lot of overhead.

        On the other hand, if you are using a function that is simple and does not require significant resource allocation, using that same function 8 times would involve very little overhead.

        I expect the libraries on the bulletin board will eventually become large, potentially on the order of 1000 to 2000 lines. Size has very little affect on overhead, rather, overhead will have more to do with the complexity of the library functions used, in conjunction with the number of times they are used.

        Comment


        • #5
          Steve is correct. The overhead involved with keeping 8 efsLibs in memory is very very small compared to the overhead involved in collecting and calculating the data for your 8 different charts.

          A compiled efs script is probably only 1kb of memory per 100 lines =).

          Comment


          • #6
            Is it correct to assume that variables in an efslib have the same scope as variables in a regular efs indicator?

            I seem to remember seeing an example of how to return an array from a library function and then the code to get those values in your regular EFS code. Does any one remember where that example is located?

            I need to able to return an array of 4 variables from a library function.

            thanks
            Last edited by scjohn; 04-12-2005, 11:42 AM.

            Comment


            • #7
              I can only get the 1st value of an array that is returned via a library function

              efslib:

              PHP Code:
              //Define the Fast1 indicator
              //Note:  it takes 2 functions to turn a KP indicator into a serial object
              function KPFast1(symbolinterval) {
                  if(
              symbol == nullsymbol getSymbol();
                  if(
              interval == nullinterval getInterval();
                  var 
              vSymbol symbol "," interval
                  
              return efsInternal("KPFast1Internal",0,symvSymbol));
              }
              function 
              KPFast1Internal(source) {
                  var 
              nBarState getBarState();
                  if ( 
              nBarState == BARSTATE_ALLBARS) {
                      
              cum1 0;
                      
              stateID 0;
                      
              // make it create a new state when it starts up.
                  
              } else if( nBarState == BARSTATE_NEWBAR) {
                      
              cum1++;
                  }
                  var 
              = new Array();
                  
              r[0] = 0.0;
                  
              r[1] = 0.0;
                  
              r[2] = 0.0;
                  
              r[3] = 0.0;

                  if( 
              stateID != ){
                      var 
              check KPdll.call("E_CHECKSTATE"stateID);
                      if( 
              check == ) {
                          
              // We have to recalculate from the first bar.
                          
              reloadEFS();
                          
              stateID 0;
                      }
                  }
                  if( 
              stateID == ) {
                      
              stateID KPdll.call("E_CREATESTATE",getUserName(),1); // the 1 tells it to use garbage collection.
                  
              }
                  
                  if( 
              stateID ) {
                      
              // we actually have gotten this far, we can go ahead and try to do something.
                      // KPdll.addFunction("E_BARVALUES", DLL.INT, DLL.CDECL, "E_BARVALUES", DLL.INT, DLL.INT, DLL.INT, DLL.INT, DLL.DOUBLE, DLL.DOUBLE, DLL.DOUBLE, DLL.DOUBLE, DLL.DOUBLE);
                      
              var bv KPdll.call("E_BARVALUES",stateID,cum1longdate(), longtime(), open(), high(), low(), close(), volume());
                      if( 
              bv != ) {
                          
              // they actually seem to have a license.
                          // this is where we calculate an actual indicator value.
                          
              KPdll.call("E_TSKPFAST1"stateID);
                          
              // return both values
                          
              r[0] = KPdll.call("E_GETRETURN",stateID,0);
                          
              r[1] = KPdll.call("E_GETRETURN",stateID,1);
                          
              r[2] = KPdll.call("E_GETRETURN",stateID,2);
                          
              r[3] = KPdll.call("E_GETRETURN",stateID,3);
                      }
                  }

                  return new Array(
              r[0], r[1], r[2], r[3]);

              now here is the main indicator.
              PHP Code:
              ....
              // global variables
              var KPLib addLibrary("KPFunctions.efsLib");   //load the KP function libaray     
              var bInit false;  //initialization flag
              var nFAST1 null;   //FAST1 object


              function main(fpSymbolfpIntervalfpPT1fpPS1fpThick1fpColor1fpPT2fpPS2fpThick2fpColor2fpPT3fpPS3fpThick3fpColor3fpPT4fpPS4fpThick4fpColor4)
              {
                  
              // one time initialization
                  
              if(bInit == false){
                      if(
              fpSymbol == nullfpSymbol getSymbol();
                      if(
              fpInterval == nullfpInterval getInterval();
                      ............................

                  
              nFAST1 KPLib.KPFast1(fpSymbolfpInterval);
                  
                  
              bInit true;
                  }   
              //end of initialization   
                  

                  
              return new Array(nFAST1.getValue(0));
                  

              The above only returns the 1st value in the array. It is apparent that I am missing some piece of the puzzle. Maybe I should be using getSeries() instead of getValue(). But I have no discussion of when to use getValue() and when to use getSeries(). There is still no documentation available for getSeries(). From the examples I have seen it would appear that they are interchangeable bout I am sure that that is not the case.

              Sure would be nice to know when to use getValue() and when to use getSeries().

              thanks

              Comment


              • #8
                Hi,

                This might be a bit of an oversight on the language design, but only efs() has the seriesIndex parameter, which allows you to retrieve a specific seriesIndex of the return, ie, the 2nd and 3rd and 4th return values.

                your efsInternal call should look like:

                efsInternal("KPFast1Internal", sym( vSymbol));

                without the '0' parameter.

                To be able to do what you want, you'll have to use the efs() call, which is similar to the efsInternal, except it references a separate EFS file instead of the efsInternal.

                ie:

                efs("KPFast1External.efs", <seriesIndexHere, either 0, 1, 2, or 3>, sym(vSymbol))

                getValue(...) and getSeries() are completely different from each other. getValue(x) retrieves a specific bar value from a Series object. ie, if you have a moving average, it can retrieve the value of the moving average -20 bars ago, or -10 bars ago, or 0 for the current bar.

                getSeries() converts a variable that was previously assigned to an EFS2 function into a Series object.

                ie:

                var v = ema(20)

                v now contains the value of the ema(20) at the time of processing. If 'v' is scoped outside of main(), it will ALWAYS contain the same ema value, the value at the time it was FIRST assigned.

                To later use this ema(20) as a parameter for another function, you have to convert it back into a Series object, by doing:

                var someOtherRSI = rsi(9, getSeries(v))

                This lets you re-use the ema(20) as pointed by 'v' as the input into another EFS2 function.

                Comment


                • #9
                  Looks like I will have to abandon the use of the function library. I would say that half of my dll's need to be able to return an array. Based upon what you said I would have to set up another folder and have half the indicators in one folder (Function library) and the other half in another folder. Not a satisfactory arrangement.

                  Comment


                  • #10
                    Hello scjohn,

                    You could use the split() method of a String object as a work around. Take your return array and build a concatenated string with a separater and return that string instead of the array. Use the split method on the other end to convert it back to the array your function needs. You may also need to do an eval() on the array elements to convert them back to numbers.
                    Jason K.
                    Project Manager
                    eSignal - an Interactive Data company

                    EFS KnowledgeBase
                    JavaScript for EFS Video Series
                    EFS Beginner Tutorial Series
                    EFS Glossary
                    Custom EFS Development Policy

                    New User Orientation

                    Comment


                    • #11
                      Hi Jason,

                      That appears to me to be an excellent workaround. I am in a similar situation as scjohn except that I was planning on calling external efs's on different timeframes. Based on discussions I have had and the testing I have performed, use of the EFS2 external reference, efs(), is also subject to the limitation scjohn has described.

                      It seems that the workaround you described would also work in my situation as well, what do you think?

                      Regards,

                      Comment


                      • #12
                        Hello Steve,

                        Yes, I think that should work. Why not use the seriesIndex parameter of efs() instead? That would be the easier way to go if you only have a few array elements in the return statement. However, I think the split method would the better way to go if the external efs is returning a large array.
                        Jason K.
                        Project Manager
                        eSignal - an Interactive Data company

                        EFS KnowledgeBase
                        JavaScript for EFS Video Series
                        EFS Beginner Tutorial Series
                        EFS Glossary
                        Custom EFS Development Policy

                        New User Orientation

                        Comment


                        • #13
                          Hi Jason,

                          The efs's I was calling are somewhat resource intensive and I had found calling them

                          myVar = efs( "myCustomEFS.efs", 0, sym( "IBM,15" ), 20, 5 );

                          using several calls for the different array items became rather expensive. Just to qualify, it has been a while since I had originally tested that feature, perhaps it is much better now. I am going to be grabbing an awful lot of data however, so I believe your suggestion will work wonderfully.

                          Just to make sure I understand what you are saying, I would make one call to get the first element of the array, then a second call to get the second element... and so on.

                          for example:

                          myVar = efs( "myCustomEFS.efs", 0, sym( "IBM,15" ), 20, 5 ); //first array element
                          myVar = efs( "myCustomEFS.efs", 1, sym( "IBM,15" ), 20, 5 ); //second array element

                          Regards,

                          Comment


                          • #14
                            Hello scjohn/Steve,

                            Looks my theory was wrong. I haven't been able to put together a working example using the split method. The efs() and efsInternal() Series functions do not appear to be to support a series of strings, only numbers.
                            Jason K.
                            Project Manager
                            eSignal - an Interactive Data company

                            EFS KnowledgeBase
                            JavaScript for EFS Video Series
                            EFS Beginner Tutorial Series
                            EFS Glossary
                            Custom EFS Development Policy

                            New User Orientation

                            Comment


                            • #15
                              Hi Jason,

                              ...too bad, that would have been nice. The idea sounded great, thanks for looking into it.

                              Regards,

                              Steve

                              Comment

                              Working...
                              X