Announcement

Collapse
No announcement yet.

Std Dev of Range

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

  • Std Dev of Range

    I am trying to create an indicator that returns the Std Dev of Range. I amd trying to use Bollinger band logic to achieve this but only able to use close. If I try and replace "Close" with "Range" I get an error, parameter 2 invalid.

    Is there a simple fix for this? Below is the code as I am attempting to use it. Thanks in advance!!

    Code:
    function preMain() {
        setStudyTitle("BandWidth");
        setCursorLabelName("BW", 0);
        setCursorLabelName("Floor", 1);
    }
     
    var bb = new BollingerStudy(300, "Range", 2.0);
     
    function main() {
        var vUpper = bb.getValue(BollingerStudy.UPPER);
        var vLower = bb.getValue(BollingerStudy.LOWER);
        var vMiddle = bb.getValue(BollingerStudy.BASIS);
        
        if(vUpper == null || vLower == null || vMiddle == null)
            return 0.0;
            
        return new Array((vUpper -vMiddle), 0.0);
    }

  • #2
    maninjapan
    “Range” is not a valid input for the legacy BollingerStudy function nor does that function allow for the use of custom variables [which Range would be since it is not a built-in data series such as Open, High, Low, etc]
    You need to use the efs2 Bollinger functions to be able to use a custom vatiable. This variable needs to be a series object so you must create a separate function or efs that calculates the range which you then call from the main function using either the efsInternal() or efsExternal() functions. Either one creates the required series object that you can then pass to the Bollinger functions
    See the EFS KnowledgeBase for the description and syntax [together with examples of the use] of these functions. Also search the forum for keywords like “efsinternal” or “efsexternal” as there are many threads [complete with examples] related to the topic as this has been covered at length before.
    That said it seems to me you are taking a rather convoluted approach to calculate the Standard Deviation given that that are already functions available that do that [again search the forum]
    Alex


    Originally posted by maninjapan View Post
    I am trying to create an indicator that returns the Std Dev of Range. I amd trying to use Bollinger band logic to achieve this but only able to use close. If I try and replace "Close" with "Range" I get an error, parameter 2 invalid.

    Is there a simple fix for this? Below is the code as I am attempting to use it. Thanks in advance!!

    Code:
    function preMain() {
        setStudyTitle("BandWidth");
        setCursorLabelName("BW", 0);
        setCursorLabelName("Floor", 1);
    }
     
    var bb = new BollingerStudy(300, "Range", 2.0);
     
    function main() {
        var vUpper = bb.getValue(BollingerStudy.UPPER);
        var vLower = bb.getValue(BollingerStudy.LOWER);
        var vMiddle = bb.getValue(BollingerStudy.BASIS);
        
        if(vUpper == null || vLower == null || vMiddle == null)
            return 0.0;
            
        return new Array((vUpper -vMiddle), 0.0);
    }

    Comment


    • #3
      Thanks Alexis, I was just taking a lead from another thread that suggested that was the easiest way to do it. I have had a go at adding a range function to a Std Dev calculation ( code below). there don't seem to be any syntax errors, but I am not getting any data on my chart from it either... Any suggestions as to what I am doing wrong here?

      Thanks


      Code:
      var nStdDev;
      var x;
      var nMean=0;
      var nSums=0;
      var aData;
      var nLength;
       
      function preMain() {
       
       
          setPriceStudy(false);
          setStudyTitle("StdDev");
          setCursorLabelName("Std Dev", 0);
          setPlotType(PLOTTYPE_HISTOGRAM, 0);
          setDefaultBarFgColor(Color.blue, 0); 
       
      }
       
      function main() {
       
       
          aData = efsInternal("range");
          nLength = 300;
                  
                  //calculate the mean
                  x=0;
                  while( x<nLength ) {
                              nMean += aData[x++];
                  }
                  nMean /= nLength;
                  
                  //calculate the sum of squares
                  x=0;
                  while( x<nLength ) {
                              nSums += ( nMean - aData[x]) * ( nMean - aData[x++] );
                  }           
                  
                              //return the StdDev
                  return( Math.sqrt( nSums / (nLength-1) ) );
      }
       
       
      var Ddiff = null;
                  
      //this is the separate function that calculates the range 
      function range() { 
       
       
       
            
              Ddiff = Math.abs(high(0) - low(0));
                  
              
         
          
          return Ddiff;
       
       
      }

      Comment


      • #4
        maninjapan
        - In your Range function you do not need to calculate the absolute value of the High-Low as the High is by definition equal or greater than the Low [hence you will never get a negative value as you would if you were - for example - calculating Open-Close or viceversa]. This is not an error per se but it is redundant coding
        - The efsInternal() function returns a series object and not an array so using aData[x] to retrieve its values is not valid syntax for that data type. To retrieve the values from a series object you need to use the getValue() method of the series object (refer to the related articles in the EFS KnowledgeBase for more information). I would reiterate my prior suggestion to search the forum for efsInternal or efsExternal where you will find many examples of how to use these functions correctly.
        - You declared nMean and nSums as global variables whereas they should be local.
        - In the equation in the return statement you incorrectly divide by nlength-1 whereas it should be nLength.
        Once you resolve these issues the script you last posted will work as expected
        You could also implement your original solution now that you have a series object in aData and pass that to the efs2 Bollinger functions [and not the legacy ones you used originally]
        That said, as I indicated in my previous reply either solution is somewhat convoluted and if you search the forum you will find that there are ready made [IOW similar to built-in] functions available that will compute the standard deviation of any series that you pass to them
        Alex


        Originally posted by maninjapan View Post
        Thanks Alexis, I was just taking a lead from another thread that suggested that was the easiest way to do it. I have had a go at adding a range function to a Std Dev calculation ( code below). there don't seem to be any syntax errors, but I am not getting any data on my chart from it either... Any suggestions as to what I am doing wrong here?

        Thanks


        Code:
        var nStdDev;
        var x;
        var nMean=0;
        var nSums=0;
        var aData;
        var nLength;
         
        function preMain() {
         
         
            setPriceStudy(false);
            setStudyTitle("StdDev");
            setCursorLabelName("Std Dev", 0);
            setPlotType(PLOTTYPE_HISTOGRAM, 0);
            setDefaultBarFgColor(Color.blue, 0); 
         
        }
         
        function main() {
         
         
            aData = efsInternal("range");
            nLength = 300;
                    
                    //calculate the mean
                    x=0;
                    while( x<nLength ) {
                                nMean += aData[x++];
                    }
                    nMean /= nLength;
                    
                    //calculate the sum of squares
                    x=0;
                    while( x<nLength ) {
                                nSums += ( nMean - aData[x]) * ( nMean - aData[x++] );
                    }           
                    
                                //return the StdDev
                    return( Math.sqrt( nSums / (nLength-1) ) );
        }
         
         
        var Ddiff = null;
                    
        //this is the separate function that calculates the range 
        function range() { 
         
         
         
              
                Ddiff = Math.abs(high(0) - low(0));
                    
                
           
            
            return Ddiff;
         
         
        }

        Comment


        • #5
          After further searching ( both the above 2 came from searches on Standard Deviation), I cam across another one. I have added a function to calculate range, then used efs internal to call this function, however I I get an error message, Invalid series name ([object series] ) in getValue() . (I have also added further code to link this in excel). It works fine when I use it with one of the designated price studies
          Is this code not designed to use price studies other than those listed? I took the efs internal from another indicator that I use where it works fine, so I think I have got that part right.

          Code:
          /*****************************************************************
          Provided By : eSignal. (c) Copyright 2004
          Study:  Standard Deviation
           
          Version 1.0 - 4/8/204
           
          Formula Parameters:     Defaults:
              nLength             25
              sPriceSource        "Close"
           
          Notes:
              This formula is intended to be used within custom formulas
              through the callFunction() function to get the standard 
              deviation of one of the following price sources.  It may also
              be used as a non-price study.
                  "Open"
                  "High"
                  "Low"
                  "Close"
                  "Volume"
           
              Example Usage:
              var nStdev = callFunction("StandardDeviation.efs", "main", 10, "Close");
              if (nStdev == null) return;
              
          *****************************************************************/
          var stdev = null;
          var meanX = null;
          var sumX = null;
          var sumX2 = null;
          var nLength = null;
          var nrg = null;
           
          function preMain() {
              setStudyTitle("DDE STDEV ");
              setCursorLabelName("StdDev", 1); 
              setPlotType(PLOTTYPE_HISTOGRAM, 0); 
              setDefaultBarFgColor(Color.blue, 0); 
              setDefaultBarFgColor(Color.red, 1); 
          }
           
          function main(nLength, sPriceSource) {
              nrg = efsInternal("range");
              if (nLength == null) nLength = 300;
              if (sPriceSource == null) sPriceSource = nrg;
              var aSource = getValue(sPriceSource, 0, -nLength);
              if (aSource == null) return null;
              
              sumX = 0;
              sumX2 = 0;
              for (i = 0; i < nLength; ++i) {
              
                  sumX += aSource[i];
                  sumX2 += (aSource[i] * aSource[i])
              }
              meanX = (sumX/nLength);
              //var stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));
              //var stdev1 = Math.max((sumX2/nLength) - (meanX*meanX));
              //if (day(0)!=day(-1)) {
              stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));
              //}
              //}else{
              //stdev = Math.max(stdev,Math. sqrt((sumX2/nLength) - (meanX*meanX)));
              //}
              
              if (stdev != null){
              var sName = "stdev" + getSymbol() + getInterval();
                   sName = sName.replace(/\$/g, ""); // remove $ from string
                  sName = sName.replace(/\#/g, ""); // remove # from string
                  sName = sName.replace(/\-/g, "");
                  sName = sName.replace(/\(/g, "");
                  sName = sName.replace(/\)/g, "");
                  sName = sName.replace(/\ /g, "_") // replace space with underscore
                  debugPrintln("DDE Link for Excel =eSignal|EFS!"+sName);
                  var ddestdev = new DDEOutput(sName);
                  }
              ddestdev.set(stdev);
              return stdev;
          }
           
          //this is the separate function that calculates the range 
          function range() { 
           
              var  Ddiff = Math.abs(high(0) - low(0));
           
              return Ddiff;  
           
          }

          Comment


          • #6
            maninjapan
            Like the BollingerStudy function referenced earlier in this thread, the getValue function [not to be confused with the similarly named getValue method of the series object] is a legacy function and only accepts specific inputs. sPriceSource is not a valid input within the context of your script hence the error. See this article in the EFS KnowledgeBase for information regarding the function and this article regarding the method
            As to your latest script to resolve the error you need to
            - remove or comment out lines 45, 46 and 47
            - replace in the for loop every instance of aSource[i] with nrg.getValue(-i)
            I am not sure I understand why you would use yet another script [which still makes use of legacy functions anyhow] rather than fixing your previous script with the suggested changes. Irrespective once you implement the simple changes I suggested in this case this formula will also work.
            Alex


            Originally posted by maninjapan View Post
            After further searching ( both the above 2 came from searches on Standard Deviation), I cam across another one. I have added a function to calculate range, then used efs internal to call this function, however I I get an error message, Invalid series name ([object series] ) in getValue() . (I have also added further code to link this in excel). It works fine when I use it with one of the designated price studies
            Is this code not designed to use price studies other than those listed? I took the efs internal from another indicator that I use where it works fine, so I think I have got that part right.

            Code:
            /*****************************************************************
            Provided By : eSignal. (c) Copyright 2004
            Study:  Standard Deviation
             
            Version 1.0 - 4/8/204
             
            Formula Parameters:     Defaults:
                nLength             25
                sPriceSource        "Close"
             
            Notes:
                This formula is intended to be used within custom formulas
                through the callFunction() function to get the standard 
                deviation of one of the following price sources.  It may also
                be used as a non-price study.
                    "Open"
                    "High"
                    "Low"
                    "Close"
                    "Volume"
             
                Example Usage:
                var nStdev = callFunction("StandardDeviation.efs", "main", 10, "Close");
                if (nStdev == null) return;
                
            *****************************************************************/
            var stdev = null;
            var meanX = null;
            var sumX = null;
            var sumX2 = null;
            var nLength = null;
            var nrg = null;
             
            function preMain() {
                setStudyTitle("DDE STDEV ");
                setCursorLabelName("StdDev", 1); 
                setPlotType(PLOTTYPE_HISTOGRAM, 0); 
                setDefaultBarFgColor(Color.blue, 0); 
                setDefaultBarFgColor(Color.red, 1); 
            }
             
            function main(nLength, sPriceSource) {
                nrg = efsInternal("range");
                if (nLength == null) nLength = 300;
                if (sPriceSource == null) sPriceSource = nrg;
                var aSource = getValue(sPriceSource, 0, -nLength);
                if (aSource == null) return null;
                
                sumX = 0;
                sumX2 = 0;
                for (i = 0; i < nLength; ++i) {
                
                    sumX += aSource[i];
                    sumX2 += (aSource[i] * aSource[i])
                }
                meanX = (sumX/nLength);
                //var stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));
                //var stdev1 = Math.max((sumX2/nLength) - (meanX*meanX));
                //if (day(0)!=day(-1)) {
                stdev = Math.sqrt((sumX2/nLength) - (meanX*meanX));
                //}
                //}else{
                //stdev = Math.max(stdev,Math. sqrt((sumX2/nLength) - (meanX*meanX)));
                //}
                
                if (stdev != null){
                var sName = "stdev" + getSymbol() + getInterval();
                     sName = sName.replace(/\$/g, ""); // remove $ from string
                    sName = sName.replace(/\#/g, ""); // remove # from string
                    sName = sName.replace(/\-/g, "");
                    sName = sName.replace(/\(/g, "");
                    sName = sName.replace(/\)/g, "");
                    sName = sName.replace(/\ /g, "_") // replace space with underscore
                    debugPrintln("DDE Link for Excel =eSignal|EFS!"+sName);
                    var ddestdev = new DDEOutput(sName);
                    }
                ddestdev.set(stdev);
                return stdev;
            }
             
            //this is the separate function that calculates the range 
            function range() { 
             
                var  Ddiff = Math.abs(high(0) - low(0));
             
                return Ddiff;  
             
            }

            Comment

            Working...
            X