Announcement

Collapse
No announcement yet.

Instancing Issues

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

  • Instancing Issues

    I have designed a number of what I call engine formulas such as MAs, Ranges, Swing Pivots, Signals etc... which are all located in one directory and then can be called multiple times from other studies rather than repeating the same functions and/or routines within each study itself, thereby making design much quicker and very flexible for new studies and enabling easier maintenance on the core routines/functions which are found in only one place. I know that the trade off might be speed access but I have balanced this against ease of development and maintenance and have tried to write code as efficiently as possible to allow multiple calls without killing cpu performance.

    However I am stuck with calling the same function using callFunction from a study loaded multiple times i.e. on how to give that call a unique identifier which has worked very well using set and get GlobalValue on multiple calls from the same study or calls from other studies which are uniquely identified. I would like an elegant way to get a solution rather than making a number of copies of the same study and manually uniquely identifying each study.

    Is there any way to perform this instancing capability using GlobalValue. Just to show an example of what I am after.

    1. I have a file say called MAStd.efs that makes the calls where before preMain() & main() I give a unique ID & setup as:-

    var sDesG = "MAStd" // main ID for study
    setGlobalValue(sDesG, true); // at the moment not useful
    var aArrPS1 = new Array(); // empty arrays created for populating
    // values for each callFunction

    then within main() I will write a call such as:-

    nResult = callFunction("/Functions/fnMA.eff", "fnMA", aArrPS1,
    sPS1MAType, ......, sDesG+"PS1");

    NOTE; further calls can be made uniquely from within this study by using different identifiers such as sDesG+"PS2" etc...

    From other studies they will already have a unique main ID given by sDesG and so each individual call will be uniquely identified.

    Once the call is made the formula engine kicks in and returns the appropriate result for MAStd.efs to display.

    Within the file fnMA.eff the input from MAStd.efs is handled as follows:-

    function fnMA(aArray, sPriceMAType, ......, ID); )

    ID = "fnMA"+ID // further identifier added for this function,

    ... process the input

    ... return the result

    } //end function

    The ID that will be for the call described before is "fnMAMAStdPS1" which has to be unique otherwise any routines accessed here will cause incorrect data being passed to other calls if they have the same ID.

    When there are no previous values to be accessed and it is a straightforward consecutive calculation then a value is returned and in fact the unique ID does not matter at all to get the right result. No global functions need to be set or played with. When a previous value is required such as in EMAs then further global IDs are created to hold those results for reuse however everything will be based on the ID construction already described before.

    As I have mentioned as long as the studies are uniquely identified and the calls from each study are also uniquely identified then you can call the engine formula as many times as you like with no problems. So GlobalVaules are not required in
    straightforward calculations but are used to hold values whether
    as arrays or individually for later processing.

    I have tried to utilize the setGlobalValue function to try to change it for each study that starts out with the same name by then trying to rename each study uniquely ie:-

    if (getGlobalValue(sDesG) == true){
    sDesG = sDesG+1;
    setGlobalValue(sDesG, true);
    }

    This has not worked as each study is then ID'd the same

    I tried to use getValue ("rawtime") and other date functions all to no avail as each would give the same result for the same studies that started out with the same main ID.

    I would appreciate any thoughts/comments to assist me to get this last need 'nailed' down and working.

    Robert

  • #2
    Robert,

    I had a similar application, where I needed to create unique study names for different instance of the same efs. It is not directly applicable, however, it may give you some ideas to work with. Here is a function in the subject efs.

    PHP Code:
    function getDefaultValues(){
        var 
    = new Array();for (0<= 19i++){s[i]=0;}
        
        var 
    i;var j;var k;var ss "";var dd 0;
        var 
    sInterval getInterval();//debugPrintln("sInterval = "+sInterval);
        
        
    var f1 = new File("default file variables.txt");
        if(
    f1.exists()) {f1.open("rt");
            for (
    0<= 9i++){
                
    ss f1.readln();  //debugPrintln("Line "+i+":"+ss);
                
    dValue ss.split(",");//debugPrintln(dValue);
                
    if(== 1){dValue;}//sets default values to default in case interval test below does not match up to a dataset
                
    if (sInterval == dValue[0]){
                    
    dValue;
                    
    //if this string has Renko in it, it allows refresh of chart
                    
    if (s[1].indexOf("Renko") > 0){r_efs 0;debugPrintln(s[1]+ " will update because it is Renko");}
            }}                
            
    f1.close();  
            for (
    2<= 9j++){s[j] = parseFloat(s[j]);/*debugPrintln(s[j]);*/}
        }
        return (
    s);
    }
    //End function getDefaultValues() 
    This is not the most efficient code (about 3 months old), pls excuse, but it works well.

    What it does is that I have multiple advanced charts running and I use different intervals for each advanced chart. I keep a look-up table in the formula output directory and this function uses the interval of the advanced chart to assign unique names to the study title, the true global variables it sets and the files each instance of the study saves.

    Here is the file it looks up.

    PHP Code:
    "default file variables.txt"
    0,basic,0,10,10,10,10,10
    1S
    ,1S_Title,0,13,9,13,16,0,5
    3S
    ,4S_Renko,1,13,9,13,16,0,5
    5S
    ,5S_Renko,1,13,9,13,16,0,5
    7S
    ,7S_Renko,1,13,9,13,16,0,5
    8S
    ,8S_Renko,1,13,9,13,16,0,5
    23S
    ,20S_Candle,1,13,9,13,16,0,5
    61S
    ,1M_Candle,1,13,9,13,16,0,5
    181S
    ,3M_Candle,1,13,9,13,16,0,5
    5M
    ,5M_Candle,1,13,9,13,16,0,5
    15M
    ,15M_Candle,1,13,9,13,16,0,5
    5T
    ,5T_Volume Candle,1,13,9,13,16,0,5
    15T
    ,15T_Volume Candle,1,13,9,13,16,0,
    Let me know if this helps you out (or sparks a better idea than having to play with these "unique" intervals)

    Regards,

    Comment


    • #3
      Thanks for posting your solution. I looked at the methodology using File I/O but in the end did not like the performance hit on writing out data, reading and modifying it, nor did I want a proliferation of files littering the disk as you cannot delete these files once created from within eSignal. I did not want to develop a table from which information could be read as that seemed inflexible.

      My goal was to have the unique ID routine work in memory with the use of GlobalValue and after some experimentation I got the result I was seeking, here it is:-

      ///////////////////////////////////////////////////////////////////////////////////
      In the chart calling the external function

      Before main() & preMain()

      // Set global value to be checked by other charts, function engines
      // to stop reinstancing problems when using same study, symbol &
      // interval as well as maintaining a totally unique ID in every case

      // Study Name for unique ID
      // This will be the only change required for each study other than
      // any routines used from within main()
      var sDesNameG = "MAMan"

      // Symbol for unique ID
      var sDesSymG = fnHashChk()

      // Interval for unique ID
      var sDesIntG = getInterval();

      // SETTING MASTER ID for study
      // This will be unique as long as the same study is not used
      // for the same symbol and interval. If it is, then the continuing
      // routine will ensure that the ID will be unique.
      var sDesMG = sDesNameG+sDesSymG+sDesIntG;

      // Now apply a unique ID for this instance for this chart
      var nDesG = fnGlobal(sDesMG);
      var sDesG = nDesG+sDesMG;

      // Useful for 1st time use in formula engines
      setGlobalValue(sDesG, false);

      var aArrPS1 = new Array(); // empty arrays created for populating

      preMain(){
      }


      main(){
      add further routines as necessary to ensure unique IDs
      i.e.:-
      nResult = callFunction("/Functions/fnMA.eff", "fnMA", aArrPS1,
      sPS1MAType, ......, sDesG+"PS1");


      }

      functions for this chart to be placed after main()

      // =============================================
      function fnHashChk(){
      // ----------------------------------------------------------------
      // Ensures that hashes and spaces in symbol name do not
      // yield errors in global arrays when using as IDs:-
      // i.e. for "YM #F" is changed to "YMCF"

      var nHashChk;
      var sDesSym = getSymbol();

      nHashChk = sDesSym.indexOf("#");

      // Routine will only be performed if "#" found
      if (nHashChk >=0 ){
      var sSplt = sDesSym.split(" #");
      // normally only need to splice 2 parts
      sDesSym = sSplt[0]+"C"+sSplt[1]
      }

      return (sDesSym);

      // ----------------------------------------------------------------
      } // END function fnHashChk()
      // =============================================

      // =============================================
      function fnGlobal( sDes ) {
      // ----------------------------------------------------------------
      // Made a limit on total numbering to 9 instances where the
      // numbering is recycled from 1 onwards. This can be easily
      // increased if necessary.

      var nID = getGlobalValue(sDes);

      if(nID == null || nID >= 9){ //resets back to 1
      nID = 1;
      }else{
      nID++;
      }

      setGlobalValue(sDes, nID);

      return (nID);

      // -----------------------------------------------------------------
      } // END function fnGlobal( sDes )
      // =============================================

      //////////////////////////////////////////////////////////////////////////////////
      In the function engine file

      function fnMA(aArray, sPriceMAType, ......, ID); )

      ID = "fnMA"+ID // further identifier added for this function,

      ... process the input
      // further IDs can be added for specific routines

      ... return the result

      } //end function

      The advantages of this system is as follows:-

      1. Everything is kept in memory; ensuring fastest access times
      2. When eSignal is closed everything is restarted from scratch
      when eSignal is restarted again so nothing to maintain
      3. The only parameter to worry about is the designator for the
      study itself, and as long as this is kept unique for all charts then no interference from multi instancing can occur.

      The only proviso for this is that the number of instances have been kept to 9, if more are required then the number can be increased easily.

      It could also be possible to functionalize the whole routine described above except for the study name. This would be another programming exercise!

      One more point is that if you access many different symbols at many different intervals then there will be hundreds (thousands?) of global arrays created which will only exist whilst eSignal is active, everything will dissappear once esignal is closed. I do not know what is the limit of placing so many global variables in memory whether there is an issue for the total number or speed degradation. If anyone has any inside on this then I would like to know. If there is then new routines will have to be written to remove Global values using removeGlobalValue() function - yet another programming exercise!

      I hope that it can be of some use to anybody facing similar problems, or if anyone has a better solution in terms of coding and/or cpu eficiency then I would appreciate any feedback.

      Robert
      Last edited by rcameron; 11-21-2003, 03:39 AM.

      Comment


      • #4
        As a further thought which I am now integrating into my coding, you can separate the ID elements by adding an underscore between each one ( i.e: +"_"+ ) - any other non alphabetic character will cause problems with GlobalValue, and then you have a designator that is not only unique but can be utilized as a record with fields separated by the underscore character, so that with the string manipulation functions available you can play around with this to your heart's content.

        For example you can store an array of data to the Unique ID designator using setGlobalValue("Unique ID", Array) and then in another chart (whether it is the same symbol, different time frame whatever), then test for that GlobalValue (i.e. getGlobalValue("Unique ID") ), ensure that specifically it is the symbol, timeframe or whatever you are trying to get from the other chart using the string manipulation functions, read in the array and then use that data for further computation.

        Instead of passing a whole array, you could store to the unique ID just an index with flags set as on/off, where if set to on, could be used to access data arrays stored in other global values based on the unique ID. I believe this would be a more efficient method of passing data values from one chart to another especially if the data arrays are large, simple one record values would be better stored in the passing GlobalValue to minimize coding. It is always striving to find the right balance between coding efficiency, cpu efficiency and memory capacity to perform a specific task - which you can iterate to "death"!

        Robert

        Comment


        • #5
          After some checking with various Futures Indicies I have had to add more routines to the function fnHashChk() to cover the problems of illegal characters being passed to GlobalValue, here is the revised version if anyone is interested:-

          // ================================================== ==============
          function fnHashChk(){
          // ----------------------------------------------------------------
          // Ensures that hashes and spaces in symbol name do not
          // yield errors in global arrays when using as IDs:-
          // i.e. for "YM #F" is changed to "YMCF"

          var nHashChk;
          var sDesSym = getSymbol();

          // Hashes
          nHashChk = sDesSym.indexOf("#");

          // Routine will only be performed if "#" found
          if (nHashChk >=0 ){
          var sSplt = sDesSym.split(" #");
          // normally only need to splice 2 parts
          sDesSym = sSplt[0]+"C"+sSplt[1]
          }

          // Spaces
          nHashChk = sDesSym.indexOf(" ");

          // Routine will only be performed if " " found
          if (nHashChk >=0 ){
          var sSplt = sDesSym.split(" ");
          // normally only need to splice 2 parts
          sDesSym = sSplt[0]+""+sSplt[1]
          }

          // Minus

          nHashChk = sDesSym.indexOf("-");

          // Routine will only be performed if " " found
          if (nHashChk >=0 ){
          var sSplt = sDesSym.split("-");
          // normally only need to splice 2 parts
          sDesSym = sSplt[0]+""+sSplt[1]
          }

          return (sDesSym);

          // ----------------------------------------------------------------
          } // END function fnHashChk()
          // ================================================== ==============






          Robert

          Comment

          Working...
          X