Announcement

Collapse
No announcement yet.

Formulas that update vs Formulas that don't

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

  • Formulas that update vs Formulas that don't

    I like Blau's Ergodic Candlestick as an indicator, but every time, before
    I can be sure exactly which way it's pointing, I have to right click on it
    and reload. Below is the formula; please tell me how to modify it so that
    it automatically stays current.

    Thanks.

    /************************************************** *****************
    Blau's Ergonomic Candlestick Oscillator; Provided By : TS Support, LLC for
    eSignal. (c) Copyright 2002
    ************************************************** ******************/

    function preMain()
    {
    setStudyTitle("ECO-11");
    setCursorLabelName("BlauECO 10",0);
    setDefaultBarFgColor(Color.lime,0);
    setDefaultBarFgColor(Color.RGB(180,155,180),1);
    setPlotType(PLOTTYPE_HISTOGRAM,1);

    addBand(0, PS_DASH, 2, Color.maroon);

    // Force the scale to be 0->100
    // setStudyMin(-.30);
    // setStudyMax(.30);

    }
    var EMA_1 = 0;
    var EMA1_1 = 0;
    var vEMA_1 = 0;
    var vEMA1_1 = 0;
    var vEco1 = 0;
    var vHisto = 0;

    function main(r,s)
    {
    if (r == null)
    r = 11;
    if(s == null)
    s = 4;

    var K = 2 / (r + 1);
    var K1 = 2 / (s + 1);

    EMA = K * (close() - open()) + (1 - K) * EMA_1;
    EMA1 = K1 * EMA + (1 - K1) * EMA1_1;
    vEMA = K * (high() - low()) + (1 - K) * vEMA_1;
    vEMA1 = K1 * vEMA + (1 - K1) * vEMA1_1;

    if (getBarState() == BARSTATE_NEWBAR){
    EMA_1 = EMA;
    EMA1_1 = EMA1;
    vEMA_1 = vEMA;
    vEMA1_1 = vEMA1;
    }
    vEco1 = EMA1 / vEMA1;
    vHisto = EMA1 / vEMA1;

    if(vEMA1 != 0)
    return new Array (vEco1,vHisto);
    else
    return;
    }

  • #2
    Steven
    The enclosed revision should fix the problem you are having
    Alex

    PHP Code:
    /*Blau's Ergonomic Candlestick Oscillator; Provided By : TS Support, LLC for
    eSignal. (c) Copyright 2002*/

    function preMain(){

        
    setStudyTitle("ECO-11");
        
    setCursorLabelName("BlauECO 10",0);
        
    setDefaultBarFgColor(Color.lime,0);
        
    setDefaultBarFgColor(Color.RGB(180,155,180),1);
        
    setPlotType(PLOTTYPE_HISTOGRAM,1);
        
    addBand(0PS_DASH2Color.maroon);

    // Force the scale to be 0->100
    //    setStudyMin(-.30);
    //    setStudyMax(.30);

    }
    var 
    EMA 0;
    var 
    EMA1 0;
    var 
    vEMA 0;
    var 
    vEMA1 0;
    var 
    EMA_1 0;
    var 
    EMA1_1 0;
    var 
    vEMA_1 0;
    var 
    vEMA1_1 0;
    var 
    vEco1 0;
    var 
    vHisto 0;

    function 
    main(r,s){
        
        if (
    == null)
            
    11;
        if(
    == null)
            
    4;

        var 
    / (1);
        var 
    K1 / (1);

        if (
    getBarState() == BARSTATE_NEWBAR){
            
    EMA_1 EMA;
            
    EMA1_1 EMA1;
            
    vEMA_1 vEMA;
            
    vEMA1_1 vEMA1;
        }
        
        
    EMA * (close() - open()) + (K) * EMA_1;
        
    EMA1 K1 EMA + (K1) * EMA1_1;
        
    vEMA * (high() - low()) + (K) * vEMA_1;
        
    vEMA1 K1 vEMA + (K1) * vEMA1_1;
     
        
    vEco1 EMA1 vEMA1;
        
    vHisto EMA1 vEMA1;

        if(
    vEMA1 != 0)
        return new Array (
    vEco1,vHisto);
        else
        return;

    Comment


    • #3
      Thanks for the corrected javascript. But study the code as I might, I still can't grasp why your code updates correctly and mine didn't. And I'm running into the same problem with a new indicator I've been experimenting with. It should be quite handy, since it is supposed to show a 10-period moving average of both the up and the down volume. But I have to always reload the indicator to find out where it REALLY is at the moment.

      Here is the code:

      // Global Variables

      var nBarCount = 0;
      var upVol = 0;
      var dnVol = 0;
      var sumDnVol = 0.0;
      var sumUpVol = 0.0;
      var avDnVol = 0.0;
      var avUpVol = 0.0;
      var x = 0;
      var nLength = 10;
      var DnVolAray = new Array(10);
      var UpVolAray = new Array(10);

      function PreMain(){
      var x;
      setPriceStudy(false);
      setCursorLabelName("Dn",0);
      setCursorLabelName("Up",1);
      setStudyTitle("TwoVol10");

      setPlotType( PLOTTYPE_LINE, 0);
      setPlotType( PLOTTYPE_LINE, 1);

      // Initialize arrays
      x=0;
      for ( x=0; x<nLength; x++ ) {
      DnVolAray[x] = 0.0;
      UpVolAray[x] = 0.0;
      }

      }

      function main() {

      if(open() > close()) {
      dnVol = getValue("Volume");
      DnVolAray.pop();
      DnVolAray.unshift(dnVol);
      } else if(open()< close()) {
      upVol = getValue("Volume");
      UpVolAray.pop();
      UpVolAray.unshift(upVol);
      }

      x = 0;
      sumDnVol = 0.0;
      sumUpVol = 0.0;
      for ( x=0; x < nLength; x++ ) {
      sumDnVol += DnVolAray[x];
      sumUpVol += UpVolAray[x];
      }

      setDefaultBarFgColor(Color.red,0);
      setDefaultBarFgColor(Color.lime,1);

      avDnVol = sumDnVol / nLength;
      avUpVol = sumUpVol / nLength;

      return new Array(avDnVol, avUpVol);
      }

      Tell me the principle I'm missing, if you can.

      Thanks.

      Comment


      • #4
        Steven
        Some indicators rely on their prior values to calculate the current ones. To do this we need to take the value of the indicator at the current bar and store it for later use. However this process needs to take place at a specific time ie when a bar has just closed else the value that we will be storing will be incomplete.
        To make sure that we will be storing the very last value of the current bar we need to wait for a new bar to be formed and to identify when this occurrs we normally use if(getBarState()==BARSTATE_NEWBAR). Inside this conditional statement we then transfer the last current value to the variable that contains the historical value. For this to happen correctly all the variables used must be global ie persistent in memory between iterations of the formula.
        Having said all this here is what was happening in your original formula
        This section of the script calculates the EMA. In this case all the variables that represent the historical values required by the EMA are identified by a _1 in the name of the variable.

        EMA = K * (close() - open()) + (1 - K) * EMA_1;
        EMA1 = K1 * EMA + (1 - K1) * EMA1_1;
        vEMA = K * (high() - low()) + (1 - K) * vEMA_1;
        vEMA1 = K1 * vEMA + (1 - K1) * vEMA1_1;


        Right after the EMA had been calculated you had this section which transferred the current values of the EMA to the variables containing the historical values

        if (getBarState() == BARSTATE_NEWBAR){
        EMA_1 = EMA;
        EMA1_1 = EMA1;
        vEMA_1 = vEMA;
        vEMA1_1 = vEMA1;
        }


        The problem here was that this happened after the indicator had calculated a new value so when a new bar occurred the value that was being stored was the most recent value of the indicator ie the one at the beginning of the new bar and not the last one of the bar that had just closed.
        This is why the indicator would increasingly go out of alignment. A reload would fix the problem because at that point the indicator was calculating all the values based on completed bars at least up until the most recent one. After that it would begin to go out of alignment again in real time until the next reload.
        In my revision I moved that second section above the one that calculates the EMA (see following code)

        if (getBarState() == BARSTATE_NEWBAR){
        EMA_1 = EMA;
        EMA1_1 = EMA1;
        vEMA_1 = vEMA;
        vEMA1_1 = vEMA1;
        }

        EMA = K * (close() - open()) + (1 - K) * EMA_1;
        EMA1 = K1 * EMA + (1 - K1) * EMA1_1;
        vEMA = K * (high() - low()) + (1 - K) * vEMA_1;
        vEMA1 = K1 * vEMA + (1 - K1) * vEMA1_1;


        This way once a new bar occurrs the value that is being transferred is the last value of the bar that just closed and not the one of the new bar which will be calculated only after the "transfer" of values has occurred. You will also see that in my revision I modified some variables to be global rather than local so that they would persist in memory on each iteration of the bar. If I did not do that then the current values of those variables would be 0 or null depending on what I assigned to it when I declared it.
        Hope this helps
        Alex

        Comment


        • #5
          Steven
          With regards to the last formula you posted the problem was similar to the one I described in my prior reply with the additional issue that you were never actually storing historical values properly. Anyhow here is a revised version that will compute correctly in real time
          Alex

          PHP Code:
          var upVol 0;
          var 
          dnVol 0;
          var 
          avDnVol 0.0;
          var 
          avUpVol 0.0;
          var 
          DnVolAray null;
          var 
          UpVolAray null;

          function 
          preMain(){
              
          setPriceStudy(false);
              
          setStudyTitle("TwoVol10");
              
          setCursorLabelName("Dn",0); 
              
          setCursorLabelName("Up",1); 
              
          setDefaultBarFgColor(Color.red,0); 
              
          setDefaultBarFgColor(Color.lime,1); 
              
          setPlotTypePLOTTYPE_LINE0); 
              
          setPlotTypePLOTTYPE_LINE1); 
          }

          function 
          main(nLength) {

              if(
          nLength==nullnLength 10;

              if(
          DnVolAray==nullDnVolAray = new Array(nLength);
              if(
          UpVolAray==nullUpVolAray = new Array(nLength);

              if(
          getBarState()==BARSTATE_NEWBAR){
                  if(
          open(-1) > close(-1)) {
                      
          DnVolAray.pop();
                      
          DnVolAray.unshift(dnVol);
                      
          dnVol volume(-1);
                  } 
                  if(
          open(-1) < close(-1)) {
                      
          UpVolAray.pop();
                      
          UpVolAray.unshift(upVol);
                      
          upVol volume(-1);
                  }
              }
              
          DnVolAray[0] = dnVol;
              
          UpVolAray[0] = upVol;

              
          0;
              var 
          sumDnVol 0.0;
              var 
          sumUpVol 0.0;

              for ( 
          x=0nLengthx++ ) {
                  
          sumDnVol += DnVolAray[x];
                  
          sumUpVol += UpVolAray[x];
              }
              
          avDnVol sumDnVol nLength;
              
          avUpVol sumUpVol nLength;

              return new Array(
          avDnVolavUpVol);

          Comment


          • #6
            Again, many thanks.

            But, another question.

            In the lines:

            if(getBarState()==BARSTATE_NEWBAR){
            if(open(-1) > close(-1)) {

            why did you specify the previous open and close, rather than the current one?

            Comment


            • #7
              Steven
              In the formula you posted some calculations need to be performed only when a bar is completed otherwise you get the problems you reported.
              If in the lines

              if(getBarState()==BARSTATE_NEWBAR){
              if(open(-1) > close(-1)) {


              I used the current open() and close() then those would be exactly the same value in the instant the first tick of a new bar is created. This means that Open would never be >< Close and the rest of the computations inside those conditional statements would never be executed. Try replacing the value (-1) with (0) and you will see that the formula will no longer work.
              For a similar reason I also store volume(-1) because otherwise the Volume on the first tick of a new bar would not be representative of the entire Volume of that bar when it will be completed.
              Alex

              Comment


              • #8
                Good answer, Alex. Thank you.

                Comment

                Working...
                X