Announcement

Collapse
No announcement yet.

eSignal shuts down when chart with a setGlobalValue() is closed

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

  • eSignal shuts down when chart with a setGlobalValue() is closed

    Hi,
    Setup: Two 5 minute charts set a global variable (both give the variable the same name) via setGlobalValue(). This global is called by one 500T chart. If one of the 5 minute charts is closed, eSignal shuts down immediately if the 500T chart is still open.

    On two different 5 min charts (only difference in time template in one is 9:30 to 16:00 and on the other chart it is dynamic to plot after-hours data) I have the same efs that sets globals (via setGlobalValue()) for say a moving average value. Both efs use the same name for the globals since there is only one lower interval chart (500 tick) that uses these globals.

    On a 500 tick chart I have a simple efs that calls the globals (via getGlobalValue()) and plots them on the price chart pane.

    At the beginning of the day, from about 8:30 am to 10:00 am I have both 5 minute charts running at the same time (both set the same global variable) but after 10:00 I only need the 9:30-16:00 chart so I close the chart with the dynamic time template.

    If I close one of the 5 minute charts it causes eSignal to shut down immediately. I’ve tried “if(vGlobal == null)” in the 500T chart but it doesn’t stop eSignal from shutting down.

    1- How does eSignal handle the variable with the same name that is set in two different charts at the same time.

    2- How does the calling efs in the lower interval chart handle the call (getGlobalsValue()) of this global variable when there are two charts with efs setting the same global variable especially when only one of the charts that set the global is closed?

    3- Is there a way to check for the existence of a particular global variable set via setGlobalValue() in an efs study? Or some way to stop execution if one of the chart that sets the global value is closed?

    I thought of naming the variable differently in the 5 min charts but I still have to check for their existence in the 500T chart to find out which global variable still exists once I close one of the 5 min charts.

    Thanks,
    Wayne
    Last edited by waynecd; 01-29-2010, 05:44 PM.

  • #2
    Wayne,

    A few caveats I've found:

    A global value created with setGlobalValue() persists until eSignal is shutdown or removeGlobalValue() is called. However, I'm not sure what happens if removeGlobalValue() is called from one script while another script is using it via getGlobalValue().

    getGlobalValue() will/should return a null if the value doesn't exist. However, given the persistence I mentioned above this won't help in your case.

    Setting the same global value from more than one running script is a bad idea especially IF THE SCRIPTS ARE ON DIFFERENT CHARTS. While all scripts within a chart are SINGLE-THREADED and the risk of two scripts setting the same value at the same time is non-existent, scripts on different charts can run in different execution threads. eSignal may or not have mutexes around setGlobaValue() to prevent values from being set at the same time.

    Setting a global value from one chart and using it in another has timing issues. While execution order of scripts within a chart can be changed so the script setting/modifying the global value is executed first this can't be done with scripts on different charts. Global values used between different charts of the same symbol will always be randomly either in sync or one tick behind. There's no way to control it.

    If you're passing an Array with only simple data objects (numbers) to setGlobalValue(), even from two scripts, you shouldn't be crashing, unless eSignal doesn't have mutexes around setGlobalValue().

    I would almost EXPECT a crash if you're passing a Series Object or a complex data structure to setGlobalValue(). For example, if you pass a moving average SERIES to it.

    Could you post the script that calls setGlobalValue() or at least the parts where setGlobalValue() is called and the variable passed to it is created? Based on that, there might be a couple of things I can suggest using postMain().
    Last edited by shortandlong; 01-31-2010, 09:10 AM.

    Comment


    • #3
      Hi shortandlong,

      Good info. The solution may have to be to close the chart with getGlobalValues before I shift the chart with setGlobalValues to one with a different time template since I can't think of anything else. Unless there is some way to test for undefined variables (globals or otherwise).

      Thanks for the info.

      Here are the test scripts. just open two 2 min charts and load the setGlobalsValues.efs in each, then open a 500V chart and load the getGlobaValue.efs. Now wait for a couple of new 2 min bars to form. Last, close the first 2 min chart and wait for a few of minutes, the eSignal error code should pop up and shut down eSignal. FWIW, I am running Windows 7 64 bit OS:
      NOTE: using the 2 min chart instead of 5 min charts just reduces how long it takes for the error to occur.

      PHP Code:
      //setGlobalValue.efs
      debugClear();
      function 
      preMain(){
          
      setPriceStudy(true);
          
      setDefaultBarFgColor(Color.RGB(128,0,0), 0);
          
      setDefaultBarFgColor(Color.blue1);
          
      setDefaultBarFgColor(Color.RGB(1270221), 2);
          
      setDefaultBarFgColor(Color.green3);
          
      setDefaultBarFgColor(Color.RGB(01280), 4);
          
      setDefaultBarFgColor(Color.black5);
          
      setCursorLabelName("MA10"0);
          
      setCursorLabelName("MA15"1);
          
      setCursorLabelName("MA20"2);
          
      setCursorLabelName("MA25"3);
          
      setCursorLabelName("MA30"4);
          
      setCursorLabelName("MA30"4);
      }
      var 
      bInit false;
      var 
      ALengths = new Array("10","15","20","25","30","30");//"30" duplicate is intentional
      var PlotArray = new Array();
      var 
      sma0 null;
      var 
      sma1 null;
      var 
      sma2 null;
      var 
      sma3 null;
      var 
      sma4 null;
      var 
      sma5 null;
      var 
      Interval0 null;

      function 
      main(){
          if(
      bInit == false){
              if(
      Interval0 == "Default" || Interval0 == nullInterval0 getInterval();
              
      vIntText Interval0
              
      for (i=0i<=ALengths.length-1i++){
                  if(
      i<=ALengths.length-2){
                      var 
      TempEMA "if(sma"+i+" == null) sma" " = sma(" ALengths[i] +" , inv(\""+Interval0+"\"))";
                      eval(
      TempEMA);
                      
      TempEMASeries "sma" " = getSeries(" "sma" ")";
                      eval(
      TempEMASeries);
                      
      PlotArray.push(eval("sma" i));
                      if(
      i==ALengths.length-2)PlotArray.push(eval("sma" i));
                  }
              }
              
      setGlobalValue("MAx6_Array",PlotArray);
              
      bInit true
          }
          return 
      PlotArray;
      }
      function 
      postMain(){
            
      removeGlobalValue"MAx6_Array" );

      and

      PHP Code:
      //getGlobalValue.efs
      function preMain(){
          
      setPriceStudy(true);
      }
      var 
      bInit false;

      function 
      main(){

          if(
      bInit==false){
              
      setDefaultBarFgColor(Color.RGB(128,0,0),0);
              
      setDefaultBarFgColor(Color.blue,1);
              
      setDefaultBarFgColor(Color.RGB(1270221),2);
              
      setDefaultBarFgColor(Color.green,3);
              
      setDefaultBarFgColor(Color.RGB(01280),4);
              
      setDefaultBarFgColor(Color.RGB(2551920),5);
              
      setDefaultBarThickness(2,0);
              
      setDefaultBarThickness(3,1);
              
      setDefaultBarThickness(4,2);
              
      setDefaultBarThickness(4,3);
              
      setDefaultBarThickness(3,4);
              
      setDefaultBarThickness(2,5);
              
      setDefaultBarStyle(PS_SOLID,0);
              
      setDefaultBarStyle(PS_SOLID,1);
              
      setDefaultBarStyle(PS_SOLID,2);
              
      setDefaultBarStyle(PS_SOLID,3);
              
      setDefaultBarStyle(PS_SOLID,4);
              
      setDefaultBarStyle(PS_DOT,5);
              
      bInit true;
          }
          
      yArray getGlobalValue("MAx6_Array");
          if(
      yArray == null) return;
          return 
      yArray;

      Last edited by waynecd; 01-31-2010, 10:49 PM.

      Comment


      • #4
        Wayne,

        The crash occurs with only one set script and one get script (same symbol, interval, and time template on both) if you do NOT remove the global value when shutting down the set script.

        Apparently, the set script deallocates the Series Object which is still pointed to in the global value. When the get script tries to access it on the next NEWBAR it crashes eSignal.

        I believe the crash you're seeing with 2 set scripts is caused by the set script you're shutting down removing the OTHER set script's series object.

        I also eliminated eval() as a possible cause. The code is much cleaner without eval().

        The scripts below seem to work ok. They use 2 global values, but they're automatically generated and located. To use:

        1) Bring up the chart you want the get script to use first and add the set script to it.
        2) Then bring up the chart with the get script.
        3) Bring up the chart with the 2nd set script.
        4) When you shut down the first set script chart, the get script will "fail over" to the 2nd set script chart.

        Note if the get script can't locate a set script, it only rechecks it when it's chart is refreshed. Force a refresh by right-clicking on the chart and selecting "Refresh".

        PHP Code:
        //setGlobalValue.efs
        //debugClear();
        function preMain(){
            
        setPriceStudy(true);
            
        setDefaultBarFgColor(Color.RGB(128,0,0), 0);
            
        setDefaultBarFgColor(Color.blue1);
            
        setDefaultBarFgColor(Color.RGB(1270221), 2);
            
        setDefaultBarFgColor(Color.green3);
            
        setDefaultBarFgColor(Color.RGB(01280), 4);
            
        setDefaultBarFgColor(Color.black5);
            
        setCursorLabelName("MA10"0);
            
        setCursorLabelName("MA15"1);
            
        setCursorLabelName("MA20"2);
            
        setCursorLabelName("MA25"3);
            
        setCursorLabelName("MA30"4);
            
        setCursorLabelName("MA30"4);
        }
        var 
        bInit false;
        var 
        ALengths = new Array("10","15","20","25","30","30");//"30" duplicate is intentional
        var PlotArray = new Array();
        /*
        var sma0 = null;
        var sma1 = null;
        var sma2 = null;
        var sma3 = null;
        var sma4 = null;
        var sma5 = null;
        */
        var Interval0 null;

        function 
        main(){
            if(
        bInit == false){
                if(
        Interval0 == "Default" || Interval0 == nullInterval0 getInterval();
                
        vIntText Interval0
                
        for (i=0i<=ALengths.length-1i++){
                    if(
        i<=ALengths.length-2){
        /*                var TempEMA = "if(sma"+i+" == null) sma" + i + " = sma(" + ALengths[i] +" , inv(\""+Interval0+"\"))";
                        eval(TempEMA);
                        TempEMASeries = "sma" + i + " = getSeries(" + "sma" + i + ")";
                        eval(TempEMASeries);
                        PlotArray.push(eval("sma" + i));
                        if(i==ALengths.length-2)PlotArray.push(eval("sma" + i));
        */
                        
        PlotArray [i] = getSeries (sma(ALengths[i], inv(Interval0)));
                        if (
        i==ALengths.length-2PlotArray [i+1] = getSeries (sma(ALengths[i], inv(Interval0)));
                    }
                }
        //        debugPrintln ( "setting " + globalValueName() );
                
        setGlobalValueglobalValueName(), PlotArray);
                
        bInit true
            }
            return 
        PlotArray;
        }

        function 
        postMain(){
        //    debugPrintln ("removing " + globalValueName());
              
        removeGlobalValueglobalValueName() );
        }

        function 
        globalValueName() {
            var 
        sStr "MAx6_Array_" getInvokerID();
            return 
        sStr;

        PHP Code:
        //getGlobalValue.efs
        function preMain(){
            
        setPriceStudy(true);
        }
        var 
        bInit false;
        var 
        sLastGlblValName null;
        var 
        bWaitForRefresh false;

        function 
        main(){

            if(
        bInit==false){
                
        setDefaultBarFgColor(Color.RGB(128,0,0),0);
                
        setDefaultBarFgColor(Color.blue,1);
                
        setDefaultBarFgColor(Color.RGB(1270221),2);
                
        setDefaultBarFgColor(Color.green,3);
                
        setDefaultBarFgColor(Color.RGB(01280),4);
                
        setDefaultBarFgColor(Color.RGB(2551920),5);
                
        setDefaultBarThickness(2,0);
                
        setDefaultBarThickness(3,1);
                
        setDefaultBarThickness(4,2);
                
        setDefaultBarThickness(4,3);
                
        setDefaultBarThickness(3,4);
                
        setDefaultBarThickness(2,5);
                
        setDefaultBarStyle(PS_SOLID,0);
                
        setDefaultBarStyle(PS_SOLID,1);
                
        setDefaultBarStyle(PS_SOLID,2);
                
        setDefaultBarStyle(PS_SOLID,3);
                
        setDefaultBarStyle(PS_SOLID,4);
                
        setDefaultBarStyle(PS_DOT,5);
                
        bInit true;
            }

            
        // Don't "wig out" (max out CPU) if the other script isn't around to set the global value
            
        if (bWaitForRefresh) {
                if (
        getBarState() == BARSTATE_ALLBARS) {
                    
        bWaitForRefresh false;
                } else {
                    return;
                }
            }
            
        //    var yArray = getGlobalValue("MAx6_Array");
            
        var yArray getFirstGlobalValue();
        //    debugPrintln ("getGlobalValue(" + sLastGlblValName + ") = " + yArray);
            
        if(yArray == null) {
                
        bWaitForRefresh true;
                return;
            }
            return 
        yArray;
        }

        function 
        getFirstGlobalValue () {
            var 
        v;
            if (
        sLastGlblValName != null) {
                
        getGlobalValue(sLastGlblValName);
                if (
        != null) return v;
            }

            for (var 
        010000i++) {
                var 
        glblValName "MAx6_Array_" i;
                
        getGlobalValue(glblValName);
                if (
        != null) {
                    
        sLastGlblValName glblValName;
                    return 
        v;
                }
            }

            
        sLastGlblValName null;
            return 
        null;

        Last edited by shortandlong; 02-01-2010, 10:14 PM.

        Comment


        • #5
          Hi shortandlong,

          I've incorporated your solution into my scripts and they work great. Creating two global variables (and checking for which exists with RETURN if neither does) is perfect.

          Eliminating the eval() cleaned up the script nicely.

          I really appreciate it.

          How do you retrieve individual values from the array of studies?
          I've tried different notations with no success like:
          PHP Code:
              debugPrintln(PlotArray[1][0]); 
          but it returns UNDEFINED.


          Wayne
          Last edited by waynecd; 02-02-2010, 07:21 AM.

          Comment


          • #6
            Wayne,

            Glad it works for you!

            Note Series Objects are "special" in that eSignal manages them outside of main(). To illustrate what I mean consider a JavaScript Array. Only YOUR code (your EFS script) manipulates the Array - the eSignal application doesn't modify it or look at it. On the other hand, a Series Object, like the return from close() assigned at global scope (outside of any function like main) to a variable, is MODIFIED by eSignal prior to calling your main(). Prior to calling main() it changes the value of the last bar and adds a new bar if necessary to the Series Object's data structure. If the chart is refreshed it removes all bars from the Series Object except the first bar.

            So, basically, a Series Object is a "pointer" to a data structure that is dynamically updated by eSignal outside of your code everytime a new trade comes in. Unlike an Array, a Series Object has things going on behind the scenes that you don't see. Series Objects are created by things like close(), builtin studies like sma(N), and efsExternal/Internal.

            This dynamic nature is related to why eSignal was crashing, since your code is passing several Series Objects (in an Array) to another script.

            (Note what you're doing is probably not "thread safe", and it may still randomly crash eSignal, most likely during heavy markets. Then again it may not happen. It's my understanding that eSignal is changing the way threading works so eSignal is more multi-threaded and performs better on multi-CPU/hyperthreaded PCs. This may have an effect on your script (as well as a bunch of my own). I believe the change is related to tick updates currently being single-thread close to the communications level. It may or may not have anything to do with charts and EFS scripts.)

            Generic documentation that applies to all Series Objects is at Click Here.

            Your code has an Array containing Series Objects. To reference a specific value:
            PHP Code:
            PlotArray [nArrayIndex].getValue (nBar)

            // for example, the previous bar of the 6th sma Series Object:

            PlotArray [5].getValue (-1
            eSignal:

            Note it is NOT possible to directly obtain the length or number of bars of a Series Object that isn't based on the current chart (in other words, a different symbol and/or interval), since functions like SeriesObject.getNumBars(), SeriesObject.getCurrentBarCount(), SeriesObject.getOldestBarIndex(), and SeriesObject.getCurrentBarIndex() don't exist!

            Series Objects with a different symbol/interval than the chart often have more or less bars than the current chart. The only way to find the number of bars is to scan SeriesObject.getValue(N) until null is returned!

            Big oversight by eSignal...
            Last edited by shortandlong; 02-02-2010, 10:09 AM.

            Comment


            • #7
              Hi shortandlong,

              Very thorough explanation.

              Thank you.

              Wayne

              Comment

              Working...
              X