Announcement

Collapse
No announcement yet.

Having more than 2 efsExternal in a script, they are executed multiple times, why?

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

  • Having more than 2 efsExternal in a script, they are executed multiple times, why?

    Hello all,

    Whenever I have a code that makes efsExternal calls to another scripts, I found that, during reload, those scripts are always more than once. I'm wondering if somebody can shed some light on this. The following is a sample skeleton script:

    var gbInit = true;
    var gmA;
    var gmB;
    var gsA;
    var gsB;

    function main() {

    if (gbInit) {
    gmA = efsExternal ("a.efs");
    gsA = getSeries (gmA, 0);
    gmB = efsExternal ("b.efs");
    gsB = getSeries (gmB, 0);
    gbInit = false;
    }
    // process and return something
    }



    The following are what I found out, and please if somebody could tell me why, let me know:

    1) Per the code is written above, whenever I do a **reload** of the script, "A" is always executed twice, whereas "B" is executed once. Why couldn't "A" just be executed once?

    2) Furthermore, the second time "A" is executed, it retains the last value of all its global variables, which is understandable, but causes frustration, since the "second" execution of "A" may produce a different (and wrong) result than the first, and these wrong results are the one used by the main script. I know... I can make provisions to always reset all global vars during "all bars", but it's too cumbersome.

    3) By the way, in the code above, if I swap the order of efsExterncall calls, to "B" being the first, and "A" being the second; during ***reload*** code "B" will be excecuted twice, while "A" executed only once.

    So, I guess, in the case of multiple efsExternal calls within a script, during reload, the first call will always be executed more than once. All I'm asking is why is this necessary, and how I should go about preventing this multiple executions to happen.

    Thanks,

    Yonas

  • #2
    Hello Yonas,

    The multiple executions you're referring to has to do with the formula engine's process for initializing the series objects for a given formula. I cannot provide any specific details as to why this is necessary. I don't think this can be avoided.

    Regarding item #2, resetting global vars that are tracking cumulative values or similar routines will need to be reset at BARSTATE_ALLBARS.
    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


    • #3
      Hello Jason:

      Thanks for responding. This confirms that I found out was not just some fluke or some silly mistake I did; but rather is an inherent "feature" of EFS language. It's too bad though, but sound like something we have to live with.

      For other reader, an illustration on how this affects your EFS script is the following. Consider a code sample that does a regression run:

      gm[0] = efsExternal ("a.efs", "ema=20");
      gm[1] = efsExternal ("a.efs", "ema=25");
      gm[2] = efsExternal ("a.efs", "ema=30");
      gm[3] = efsExternal ("a.efs", "ema=35");
      gm[4] = efsExternal ("a.efs", "ema=40");

      If the code were to only have gm[0], no gm[1:4], the code would takes 10 secs to complete.

      If the code were to have gm[0] and gm[1], it would take 30 secs, *not* 20 secs. Why? Because it runs gm[0] twice, and run gm[1] once.

      If the code were to have gm[0], [1], and [2]. Then it would take 60 secs, with gm[0] executed 3 times, gm[1] executed 2 times, and gm[0] run once.


      gm[0] only: 10 secs
      gm[0:1]: 30 secs
      gm[0:2]: 60 secs
      gm[0:3]: 100 secs
      gm[0:4]: 150 secs

      So you can see, if you were to have 5 of these efs external calls in your script, instead of incurring 5x backtesting time, you have to deal with 15x.

      Would this be something that will be fixed in the next eSignal release?

      Thanks,

      Yonas

      Comment


      • #4
        Hi Jason,

        I have run into exactly the same issue as Yonas. I am, however, not sure how to reset the global variables on BARSTATE_ALLBARS. Can you please give me an example? Is this done inside the bInit routine? Also, does this take care of the ptoblem iof you have say 4 efsExtrenals in the bInit routine? Thank you for any help you can provide.
        Regards,
        Jane

        Originally posted by JasonK
        Hello Yonas,

        The multiple executions you're referring to has to do with the formula engine's process for initializing the series objects for a given formula. I cannot provide any specific details as to why this is necessary. I don't think this can be avoided.

        Regarding item #2, resetting global vars that are tracking cumulative values or similar routines will need to be reset at BARSTATE_ALLBARS.

        Comment


        • #5
          Jane
          Just reset the global variables at BARSTATE_ALLBARS to the same values you set them when you declared them (see example below)
          Alex
          PHP Code:
          var myVar1 0;
          var 
          myVar2 100
          //etc
          function main(){
              if(
          getBarState()==BARSTATE_ALLBARS){
                  
          myVar1 0;
                  
          myVar2 100;
                  
          //etc
              
          }
              
          //rest of your code 

          Originally posted by jg
          Hi Jason,

          I have run into exactly the same issue as Yonas. I am, however, not sure how to reset the global variables on BARSTATE_ALLBARS. Can you please give me an example? Is this done inside the bInit routine? Also, does this take care of the ptoblem iof you have say 4 efsExtrenals in the bInit routine? Thank you for any help you can provide.
          Regards,
          Jane

          Comment


          • #6
            Re: -

            Hi Alex,

            Thank you very much for your reply and example. I am sorry but although I understand the example, I don't understand how to put it together with the efsExternals I am calling in my bInit routine to make my code run. I am including a code snippet below.

            // Global Variables
            var trailUp = null;
            var trailDwn = null;
            var testLong = null;
            var testShort = null;
            var nStopLoss = null;
            var nEntry = null;
            var nStop = null;
            var bPersist = 3;
            var barsPersist = bPersist;
            var nTarget = null;
            var bTargetBreach = false;
            var bInit = false; // initialization flag
            var active = false; // flag to indicate we're in a trade or that a trade signal has triggered
            var entryType = null; // indicates type of entry; i.e. long or short

            var tU_p_series, tU_series, tD_p_series, tD_series;
            var nL_id_series, nL_series, nL_stp_series, nS_id_series, nS_series, nS_stp_series;

            function main(PriceScale, Tick) {
            // Back Testing formula.
            if (getCurrentBarIndex() == 0) return;

            if(bInit == false) {
            // Initialize trailing stops for longs and shorts
            trailUp = efsExternal("\\JaneFormulas\\Trail_Up_v1.00.efs", "EXPONENTIAL", "EXPONENTIAL", PriceScale, 0.30, 2, 6, 0, Tick); // returns protectUp, trailUp, trailUp_End values
            tU_p_series = getSeries(trailUp, 0); // convert protectUp values into a series
            tU_series = getSeries(trailUp, 1); // convert trailUp values into a series

            trailDwn = efsExternal("\\JaneFormulas\\Trail_Down_v1.00.efs" , "EXPONENTIAL", "EXPONENTIAL", PriceScale, 0.30, 2, 6, 0, Tick); // returns protectDown, trailDown, trailDown_End values
            tD_p_series = getSeries(trailDwn, 0); // convert protectDown values into a series
            tD_series = getSeries(trailDwn, 1); // convert trailDown values into a series

            // This code block contains the trigger efs that are to be back tested
            // Long triggers
            testLong = efsExternal("\\JaneFormulas\\BackTesting\\Patterns \\C2_Buy_v1.06b.efs", PriceScale, Tick, 1); // returns id, entry, stop loss values
            nL_id_series = getSeries(testLong, 0); // convert long trigger id values into a series
            nL_series = getSeries(testLong, 1); // convert long trigger entry values into a series
            nL_stp_series = getSeries(testLong, 2); // convert long trigger stop loss values into a series object

            // Short triggers
            testShort = efsExternal("\\Jane Formulas\\BackTesting\\Patterns\\C2_Sell_v1.06b.ef s", PriceScale, Tick, 1); // returns id, entry, stop loss values
            nS_id_series = getSeries(testShort, 0); // convert short trigger id values into a series
            nS_series = getSeries(testShort, 1); // convert short trigger entry values into a series
            nS_stp_series = getSeries(testShort, 2); // convert short trigger stop loss values into a series object

            bInit = true; // Prevents this code block from executing again.
            }

            At this point I am not sure whether to use both bInit and BARSTATE_ALLBARS, or one of them and how and how to reset my global variables. Does the BARSTATE_ALLBARS come before or after the bInit routine? Please, please help. Thank you very much for all your help and guidance. I really am trying to learn this but cannot figure out the difference between bInit and BARSTATE_ALLBARS. I know bInit does not reset global variables but that is about it. Where can I learn more about this and see some examples? Please advise. Thank you very much.

            Regards,
            Jane


            .
            Originally posted by Alexis C. Montenegro
            Jane
            Just reset the global variables at BARSTATE_ALLBARS to the same values you set them when you declared them (see example below)
            Alex
            PHP Code:
            var myVar1 0;
            var 
            myVar2 100
            //etc
            function main(){
                if(
            getBarState()==BARSTATE_ALLBARS){
                    
            myVar1 0;
                    
            myVar2 100;
                    
            //etc
                
            }
                
            //rest of your code 

            Comment


            • #7
              Re: Re:

              Jane
              I am not sure at this point which issue you are referring to in Yonas' post.
              If you are referring to the multiple executions of ALLBARS then this will occur any time the inv(), sym(), efInternal() or efsExternal() functions are called and as explained by Jason in this and other threads this a requirement of the efs engine to create the necessary dependencies.
              As to the bInit (or bInitialized or however you name the boolean variable) routine this is just a user created routine used to initialize the variables once only (while the boolean variable is set to false). However as you already are aware global variables do not reinitialize if you refresh the chart or request more data by scrolling back. In this case if you want these variables to be reinitialized you need to enclose them in a check for ALLBARS which occurs once (keeping in mind the exception above) when the data is fully loaded
              You can use both a bInit routine and a check for ALLBARS or just a check for ALLBARS and in many cases this is just a matter of personal choice.
              I don't think there is a specific location requirement. I personally check for ALLBARS first. Others may have different opinions, methods, preferences, etc. You can find a detailed example of how to use both (actually in that example ALLBARS is used to call a function in which global variables are reset) in the CoronaChartCyclePeriod.efs which is posted here
              Alex


              Originally posted by jg
              Hi Alex,

              Thank you very much for your reply and example. I am sorry but although I understand the example, I don't understand how to put it together with the efsExternals I am calling in my bInit routine to make my code run. I am including a code snippet below.

              // Global Variables
              var trailUp = null;
              var trailDwn = null;
              var testLong = null;
              var testShort = null;
              var nStopLoss = null;
              var nEntry = null;
              var nStop = null;
              var bPersist = 3;
              var barsPersist = bPersist;
              var nTarget = null;
              var bTargetBreach = false;
              var bInit = false; // initialization flag
              var active = false; // flag to indicate we're in a trade or that a trade signal has triggered
              var entryType = null; // indicates type of entry; i.e. long or short

              var tU_p_series, tU_series, tD_p_series, tD_series;
              var nL_id_series, nL_series, nL_stp_series, nS_id_series, nS_series, nS_stp_series;

              function main(PriceScale, Tick) {
              // Back Testing formula.
              if (getCurrentBarIndex() == 0) return;

              if(bInit == false) {
              // Initialize trailing stops for longs and shorts
              trailUp = efsExternal("\\JaneFormulas\\Trail_Up_v1.00.efs", "EXPONENTIAL", "EXPONENTIAL", PriceScale, 0.30, 2, 6, 0, Tick); // returns protectUp, trailUp, trailUp_End values
              tU_p_series = getSeries(trailUp, 0); // convert protectUp values into a series
              tU_series = getSeries(trailUp, 1); // convert trailUp values into a series

              trailDwn = efsExternal("\\JaneFormulas\\Trail_Down_v1.00.efs" , "EXPONENTIAL", "EXPONENTIAL", PriceScale, 0.30, 2, 6, 0, Tick); // returns protectDown, trailDown, trailDown_End values
              tD_p_series = getSeries(trailDwn, 0); // convert protectDown values into a series
              tD_series = getSeries(trailDwn, 1); // convert trailDown values into a series

              // This code block contains the trigger efs that are to be back tested
              // Long triggers
              testLong = efsExternal("\\JaneFormulas\\BackTesting\\Patterns \\C2_Buy_v1.06b.efs", PriceScale, Tick, 1); // returns id, entry, stop loss values
              nL_id_series = getSeries(testLong, 0); // convert long trigger id values into a series
              nL_series = getSeries(testLong, 1); // convert long trigger entry values into a series
              nL_stp_series = getSeries(testLong, 2); // convert long trigger stop loss values into a series object

              // Short triggers
              testShort = efsExternal("\\Jane Formulas\\BackTesting\\Patterns\\C2_Sell_v1.06b.ef s", PriceScale, Tick, 1); // returns id, entry, stop loss values
              nS_id_series = getSeries(testShort, 0); // convert short trigger id values into a series
              nS_series = getSeries(testShort, 1); // convert short trigger entry values into a series
              nS_stp_series = getSeries(testShort, 2); // convert short trigger stop loss values into a series object

              bInit = true; // Prevents this code block from executing again.
              }

              At this point I am not sure whether to use both bInit and BARSTATE_ALLBARS, or one of them and how and how to reset my global variables. Does the BARSTATE_ALLBARS come before or after the bInit routine? Please, please help. Thank you very much for all your help and guidance. I really am trying to learn this but cannot figure out the difference between bInit and BARSTATE_ALLBARS. I know bInit does not reset global variables but that is about it. Where can I learn more about this and see some examples? Please advise. Thank you very much.

              Regards,
              Jane

              .

              Comment


              • #8
                Re: Re: Re:

                Hi Alex,

                Thank you very much for your reply. I am beginning to get it and will study the code reference you sent. My first inclination was to use both the bInit routine as well as an ALLBARS check. I just did not know if it would work as both seem to do the same thing.
                Thank you very much for your time and help.

                Regards,
                Jane


                Originally posted by Alexis C. Montenegro
                Jane
                I am not sure at this point which issue you are referring to in Yonas' post.
                If you are referring to the multiple executions of ALLBARS then this will occur any time the inv(), sym(), efInternal() or efsExternal() functions are called and as explained by Jason in this and other threads this a requirement of the efs engine to create the necessary dependencies.
                As to the bInit (or bInitialized or however you name the boolean variable) routine this is just a user created routine used to initialize the variables once only (while the boolean variable is set to false). However as you already are aware global variables do not reinitialize if you refresh the chart or request more data by scrolling back. In this case if you want these variables to be reinitialized you need to enclose them in a check for ALLBARS which occurs once (keeping in mind the exception above) when the data is fully loaded
                You can use both a bInit routine and a check for ALLBARS or just a check for ALLBARS and in many cases this is just a matter of personal choice.
                I don't think there is a specific location requirement. I personally check for ALLBARS first. Others may have different opinions, methods, preferences, etc. You can find a detailed example of how to use both (actually in that example ALLBARS is used to call a function in which global variables are reset) in the CoronaChartCyclePeriod.efs which is posted here
                Alex

                Comment

                Working...
                X