Announcement

Collapse
No announcement yet.

Problem calculating Stochastic for multiple timeframes

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem calculating Stochastic for multiple timeframes

    Hello,

    I have modified the CustomStoch.efs study to calculate the Stochastic for 4 time frames.
    Below is a snippet of code in which the problem seems to occur.
    For some reason, the Stochastics for interval 1 and 2 do not calculate.
    I have confirmed that all variables are defined correctly.

    As all four Stochastics are calculated in a similar manner, I have no idea what the cause is.

    PHP Code:
    function main(KLength,KSmoothing,DLength,Symbol,Interval,Upper,Lower,Params
    {
       
    chartInt getInterval()

       if (
    debugLevel 0debugPrintln("CustStoch: AFTER: getInterval() = " chartInt "\tInterval = " Interval

        if(
    bInit == false){
            if(
    Symbol == nullSymbol getSymbol();
            if(
    Interval == nullInterval chartInt;
            
    Interval_2  Interval 2;    
            
    Interval_3  Interval 3;        
            
    Interval_4  Interval 4;
            var 
    vSymbol_1 Symbol+","+Interval;
            var 
    vSymbol_2 Symbol+","+Interval_2;
            var 
    vSymbol_3 Symbol+","+Interval_3;
            var 
    vSymbol_4 Symbol+","+Interval_4;

            if (
    debugLevel 0debugPrintln("Interval: " Interval "\tInterval_2: " Interval_2 "\tInterval_3: " Interval_3 "\tInterval_4: " Interval_4);        
            if (
    debugLevel 0debugPrintln("vSymbol_1: " vSymbol_1 "\tvSymbol_2: " vSymbol_2 "\tvSymbol_3: " vSymbol_3 "\tvSymbol_4: " vSymbol_4);        
          
            
    xStochK_1 stochK(KLength,KSmoothing,DLength,sym(vSymbol_1));        xStochD_1 stochD(KLength,KSmoothing,DLength,sym(vSymbol_1));
            if (
    debugLevel 0debugPrintln("xStochK_1: " xStochK_1 "\txStochD_1: " xStochD_1);
            
            
    xStochK_2 stochK(KLength,KSmoothing,DLength,sym(vSymbol_2));        xStochD_2 stochD(KLength,KSmoothing,DLength,sym(vSymbol_2));
            if (
    debugLevel 0debugPrintln("xStochK_2: " xStochK_2 "\txStochD_2: " xStochD_2);
            
            
    xStochK_3 stochK(KLength,KSmoothing,DLength,sym(vSymbol_3));        xStochD_3 stochD(KLength,KSmoothing,DLength,sym(vSymbol_3));
            if (
    debugLevel 0debugPrintln("xStochK_3: " xStochK_3 "\txStochD_3: " xStochD_3);
            
            
    xStochK_4 stochK(KLength,KSmoothing,DLength,sym(vSymbol_4));        xStochD_4 stochD(KLength,KSmoothing,DLength,sym(vSymbol_4));
            if (
    debugLevel 0debugPrintln("xStochK_4: " xStochK_4 "\txStochD_4: " xStochD_4);
            
            
    addBandUpperPS_SOLID1Color.black,"Upper");
            
    addBandLowerPS_SOLID1Color.black,"Lower");
            
    setShowTitleParameters(eval(Params));
            
    bInit true;
        }

    Output from the above code is
    PHP Code:
    CustStochAFTERgetInterval() = 10      Interval null
    Interval
    10      Interval_220          Interval_330            Interval_440
    vSymbol_1
    ES #F,10  vSymbol_2: ES #F,20     vSymbol_3: ES #F,30   vSymbol_4: ES #F,40
    xStochK_1null                     xStochD_1null
    xStochK_2
    null                     xStochD_2null
    xStochK_3
    44.26229508196721        xStochD_336.458169088334586
    xStochK_4
    25.471698113207548       xStochD_423.642081189251016 
    Thank you
    Mark

  • #2
    Hi markdman,

    The problem is that Interval is defined as a string and to perform your calculation it must be a number. Intervals that won't work are "D, W, M", Tick, and Volume intervals.

    Try the code below:

    Wayne

    PHP Code:
    debugClear();
    var 
    aFPArray = new Array(); 
    function 
    preMain() {
    var 
    x=0
        
    aFPArray[x] = new FunctionParameter"KLength"FunctionParameter.NUMBER);
        
    withaFPArray[x++] ) {
            
    setName"%K (Fast)" );
            
    setLowerLimit);
            
    setUpperLimit200 );
            
    addOption); 
            
    addOption14 ); 
            
    setDefault);
        }  
        
    aFPArray[x] = new FunctionParameter"KSmoothing"FunctionParameter.NUMBER);
        
    withaFPArray[x++] ) {
            
    setName"%K Smooth");
            
    setLowerLimit);
            
    setUpperLimit200 );
            
    addOption); 
            
    addOption); 
            
    setDefault);
        }  
        
    aFPArray[x] = new FunctionParameter"DLength"FunctionParameter.NUMBER);
        
    withaFPArray[x++] ) {
            
    setName"%D (slow)" );
            
    setLowerLimit);
            
    setUpperLimit200 );
            
    addOption); 
            
    setDefault);
        }  
        
    aFPArray[x] = new FunctionParameter"vSymbol"FunctionParameter.STRING); 
        
    withaFPArray[x++] ) { 
            
    setName"Symbol" ); 
            
    setDefault"" ); 
        }   
        
    aFPArray[x] = new FunctionParameter"Interval"FunctionParameter.NUMBER); 
        
    withaFPArray[x++] ) { 
            
    setName"Price Interval" ); 
            
    addOption);
            
    addOption);
            
    addOption10 );
            
    addOption15 );
            
    addOption30 );
            
    addOption60 );
            
    addOption120 );
            
    addOption240 );
            
    setDefault); 
        }   
        
    aFPArray[x] = new FunctionParameter"Upper"FunctionParameter.NUMBER);
        
    withaFPArray[x++] ) {
            
    setName"Top Band" );
            
    setLowerLimit(50);        
            
    setUpperLimit(100);
            
    addOption70 );
            
    addOption80 ); 
            
    setDefault80 );
        }  
        
    aFPArray[x] = new FunctionParameter"Lower"FunctionParameter.NUMBER);
        
    withaFPArray[x++] ) {
            
    setName"Bottom Band" );
            
    setLowerLimit(1);        
            
    setUpperLimit(50);
            
    addOption20 ); 
            
    addOption30 ); 
            
    setDefault20 );
        }  

        
    aFPArray[x] = new FunctionParameter"Params"FunctionParameter.BOOLEAN); 
        
    withaFPArray[x++] ) { 
            
    setName"Show Parameters" ); 
            
    setDefaultfalse ); 
        }       
    }
    var 
    debugLevel 1;
    var 
    bInit false;

    function  
    main(KLength,KSmoothing,DLength,Symbol,Interval,Upper,Lower,Params){

    //   if (debugLevel > 0) debugPrintln("CustStoch: AFTER: getInterval() = " + chartInt + "\tInterval = " + Interval) 

        
    if(bInit == false){
            
    chartInt getInterval()
            if(
    Symbol == nullSymbol getSymbol();
            if(
    Interval == nullInterval chartInt;
            
    Interval_2  Interval 2;    
            
    Interval_3  Interval 3;        
            
    Interval_4  Interval 4;
            var 
    vSymbol_1 Symbol+","+Interval;
            var 
    vSymbol_2 Symbol+","+Interval_2;
            var 
    vSymbol_3 Symbol+","+Interval_3;
            var 
    vSymbol_4 Symbol+","+Interval_4;

            if (
    debugLevel 0debugPrintln("Interval: " Interval "\tInterval_2: " Interval_2 "\tInterval_3: " Interval_3 "\tInterval_4: " Interval_4);        
            if (
    debugLevel 0debugPrintln("vSymbol_1: " vSymbol_1 "\tvSymbol_2: " vSymbol_2 "\tvSymbol_3: " vSymbol_3 "\tvSymbol_4: " vSymbol_4);        
          
            
    xStochK_1 =  stochK(KLength,KSmoothing,DLength,sym(vSymbol_1));        xStochD_1 =  stochD(KLength,KSmoothing,DLength,sym(vSymbol_1));
            if (
    debugLevel 0debugPrintln("xStochK_1: " xStochK_1 "\txStochD_1: " xStochD_1);
            
            
    xStochK_2 =  stochK(KLength,KSmoothing,DLength,sym(vSymbol_2));        xStochD_2 =  stochD(KLength,KSmoothing,DLength,sym(vSymbol_2));
            if (
    debugLevel 0debugPrintln("xStochK_2: " xStochK_2 "\txStochD_2: " xStochD_2);
            
            
    xStochK_3 =  stochK(KLength,KSmoothing,DLength,sym(vSymbol_3));        xStochD_3 =  stochD(KLength,KSmoothing,DLength,sym(vSymbol_3));
            if (
    debugLevel 0debugPrintln("xStochK_3: " xStochK_3 "\txStochD_3: " xStochD_3);
            
            
    xStochK_4 =  stochK(KLength,KSmoothing,DLength,sym(vSymbol_4));        xStochD_4 =  stochD(KLength,KSmoothing,DLength,sym(vSymbol_4));
            if (
    debugLevel 0debugPrintln("xStochK_4: " xStochK_4 "\txStochD_4: " xStochD_4);
            
            
    addBandUpperPS_SOLID1Color.black,"Upper");
            
    addBandLowerPS_SOLID1Color.black,"Lower");
            
    setShowTitleParameters(eval(Params));
            
    bInit true;
        }
    //debugPrintln(chartInt);

    Comment


    • #3
      I should have added that if you need to use "D, W, M", Tick, and Volume intervals you can calculate the other intervals using something like:

      if(Interval == null) Interval = getInterval();
      if(Interval == "D") Interval_2 = "W";
      else if(...

      Wayne

      Comment


      • #4
        Thank you Wayne for your replies.

        Looking at my output at the bottom of my initial post, the intervals were calculated correctly and hence the 4 Symbol vars were set to the expected values.

        I have not been able to find any JavaScript reference that defines the outcome of multiplying a number by a string.

        It seems that
        number + string ==> string
        number * sting ==> number.

        If I change the code to
        PHP Code:
         var vSymbol_4 Symbol+","+Interval 4
        this still produces the correct string i.e. ES #F, 40 and that is with the Interval parameter defined as a string.

        The problem still remains - why do some of the calculations of the Stochastic return a value and some don't.

        If it were the longer timeframes, then it may be due to a lack of data, but it seems to be the smaller timeframes that don't work.

        Thank you
        Mark

        Comment


        • #5
          hi markdman,

          Here is a link that explains the string to number conversion:


          If the "Interval" variable is a string that can be converted to a number then the following script will plot all 4 stochastic conbinations. However, tick (55T), volume (500V), and letter ("D") intervals will not convert.

          Here is code that charts all 4 sets of stochastic plots with the "Interval" set as STRING as you originally had it:

          PHP Code:
          debugClear();
          var 
          aFPArray = new Array(); 
          function 
          preMain() {
          var 
          x=0
              
          aFPArray[x] = new FunctionParameter"KLength"FunctionParameter.NUMBER);
              
          withaFPArray[x++] ) {
                  
          setName"%K (Fast)" );
                  
          setLowerLimit);
                  
          setUpperLimit200 );
                  
          addOption); 
                  
          addOption14 ); 
                  
          setDefault);
              }  
              
          aFPArray[x] = new FunctionParameter"KSmoothing"FunctionParameter.NUMBER);
              
          withaFPArray[x++] ) {
                  
          setName"%K Smooth");
                  
          setLowerLimit);
                  
          setUpperLimit200 );
                  
          addOption); 
                  
          addOption); 
                  
          setDefault);
              }  
              
          aFPArray[x] = new FunctionParameter"DLength"FunctionParameter.NUMBER);
              
          withaFPArray[x++] ) {
                  
          setName"%D (slow)" );
                  
          setLowerLimit);
                  
          setUpperLimit200 );
                  
          addOption); 
                  
          setDefault);
              }  
              
          aFPArray[x] = new FunctionParameter"vSymbol"FunctionParameter.STRING); 
              
          withaFPArray[x++] ) { 
                  
          setName"Symbol" ); 
                  
          setDefault"" ); 
              }   
              
          aFPArray[x] = new FunctionParameter"Interval"FunctionParameter.STRING); 
              
          withaFPArray[x++] ) { 
                  
          setName"Price Interval" ); 
                  
          addOption);
                  
          addOption);
                  
          addOption);
                  
          addOption10 );
                  
          addOption15 );
                  
          addOption30 );
                  
          addOption60 );
                  
          addOption120 );
                  
          addOption240 );
                  
          setDefault); 
              }   
              
          aFPArray[x] = new FunctionParameter"Upper"FunctionParameter.NUMBER);
              
          withaFPArray[x++] ) {
                  
          setName"Top Band" );
                  
          setLowerLimit(50);        
                  
          setUpperLimit(100);
                  
          addOption70 );
                  
          addOption80 ); 
                  
          setDefault80 );
              }  
              
          aFPArray[x] = new FunctionParameter"Lower"FunctionParameter.NUMBER);
              
          withaFPArray[x++] ) {
                  
          setName"Bottom Band" );
                  
          setLowerLimit(1);        
                  
          setUpperLimit(50);
                  
          addOption20 ); 
                  
          addOption30 ); 
                  
          setDefault20 );
              }  

              
          aFPArray[x] = new FunctionParameter"Params"FunctionParameter.BOOLEAN); 
              
          withaFPArray[x++] ) { 
                  
          setName"Show Parameters" ); 
                  
          setDefaultfalse ); 
              }       
          }
          var 
          debugLevel 1;
          var 
          bInit false;

          function   
          main(KLength,KSmoothing,DLength,Symbol,Interval,Upper,Lower,Params){

          //   if (debugLevel > 0) debugPrintln("CustStoch: AFTER: getInterval() = " + chartInt + "\tInterval = " + Interval) 
              
          if(bInit == false){
                  
          chartInt getInterval()
                  if(
          Symbol == nullSymbol getSymbol();
                  if(
          Interval == nullInterval chartInt;
                  
          Interval_2  Interval 2;    
                  
          Interval_3  =  Interval 3;        
                  
          Interval_4  =  Interval 4;
                  var 
          vSymbol_1 Symbol+","+Interval;
                  var 
          vSymbol_2 Symbol+","+Interval_2;
                  var 
          vSymbol_3 Symbol+","+Interval_3;
                  var 
          vSymbol_4 Symbol+","+Interval_4;

                  if (
          debugLevel 0debugPrintln("Interval: " Interval "\tInterval_2: " Interval_2 "\tInterval_3: " Interval_3 "\tInterval_4: " Interval_4);        
                  if (
          debugLevel 0debugPrintln("vSymbol_1: " vSymbol_1 "\tvSymbol_2: " vSymbol_2 "\tvSymbol_3: " vSymbol_3 "\tvSymbol_4: " vSymbol_4);        
                
                  
          xStochK_1 =   stochK(KLength,KSmoothing,DLength,sym(vSymbol_1));
                  
          xStochD_1 =   stochD(KLength,KSmoothing,DLength,sym(vSymbol_1));
                  if (
          debugLevel 0debugPrintln("xStochK_1: " xStochK_1 "\txStochD_1: " xStochD_1);
                  
                  
          xStochK_2 =   stochK(KLength,KSmoothing,DLength,sym(vSymbol_2));        
                  
          xStochD_2 =   stochD(KLength,KSmoothing,DLength,sym(vSymbol_2));
                  if (
          debugLevel 0debugPrintln("xStochK_2: " xStochK_2 "\txStochD_2: " xStochD_2);
                  
                  
          xStochK_3 =   stochK(KLength,KSmoothing,DLength,sym(vSymbol_3));        
                  
          xStochD_3 =   stochD(KLength,KSmoothing,DLength,sym(vSymbol_3));
                  if (
          debugLevel 0debugPrintln("xStochK_3: " xStochK_3 "\txStochD_3: " xStochD_3);
                  
                  
          xStochK_4 =   stochK(KLength,KSmoothing,DLength,sym(vSymbol_4));        
                  
          xStochD_4 =   stochD(KLength,KSmoothing,DLength,sym(vSymbol_4));
                  if (
          debugLevel 0debugPrintln("xStochK_4: " xStochK_4 "\txStochD_4: " xStochD_4);
                  
                  
          addBandUpperPS_SOLID1Color.black,"Upper");
                  
          addBandLowerPS_SOLID1Color.black,"Lower");
                  
          setShowTitleParameters(eval(Params));
                  
          bInit true;
              }
          //debugPrintln(chartInt);
              
          return new Array(getSeries(xStochK_1),getSeries(xStochD_1),getSeries(xStochK_2),getSeries(xStochD_2),
                               
          getSeries(xStochK_3),getSeries(xStochD_3),getSeries(xStochK_4),getSeries(xStochD_4));

          wayne
          Attached Files

          Comment


          • #6
            Just in case I missunderstood your question and you only want the ouput of single values then change your debugPrintln() statements to:

            PHP Code:
                    if (debugLevel 0debugPrintln("xStochK_1: " xStochK_1.getValue(0) + "\txStochD_1: " xStochD_1.getValue(0));
                    if (
            debugLevel 0debugPrintln("xStochK_2: " xStochK_2.getValue(0) + "\txStochD_2: " xStochD_2.getValue(0));
                    if (
            debugLevel 0debugPrintln("xStochK_3: " xStochK_3.getValue(0) + "\txStochD_3: " xStochD_3.getValue(0));
                    if (
            debugLevel 0debugPrintln("xStochK_4: " xStochK_4.getValue(0) + "\txStochD_4: " xStochD_4.getValue(0)); 
            Notes:
            1- Calling individual values are usually called from outside the "bInit" IF-THEN statement so they continually update instead of being called only once inside the "bInit".

            2-
            getValue(-1) gets the previous bar
            getValue(-2) gets the value for 2 bars back, etc

            3- To get individual values, the call to xStockK_?.getValue(0) etc should be outside of the bInit. As I understand it, if called within the "bInit" routine the xStoch... using the charts internal interval to call individual values will return null but if you use external intervals as the script does for vSymbol_2, etc. then you can retrive the most current value only once. The why this is this way I can only speculate that the external call initializes the series and for the internal interval the series is initialized on the second call of main.

            Wayne
            Last edited by waynecd; 02-06-2010, 10:44 AM.

            Comment


            • #7
              Mark

              The problem still remains - why do some of the calculations of the Stochastic return a value and some don't.
              The following screenshot should provide a graphical illustration as to why the study based on the chart interval will return a null on the first bar of the chart [ie when the bInit routine is executed] and instead return values when based on external intervals



              Any time that a call is made to another symbol and/or interval [or to efsInternal() or efsExternal()] the main efs stops execution, and queues a delayed execution. The efs engine then executes the called symbol and/or interval first [and any efsInternal() or efsExternal() calls] and then re-executes the original main efs (this is to allow the efs engine to manage all the dependencies)
              So when the bInit routine runs, the study based on the chart interval will return null as that study is not yet fully primed however the studies based on the external intervals will return a value if the data for the intervals they are based on starts enough back in time for the studies to be fully primed in correspondence of that first bar in the chart
              Note that the Time Template can affect this behavior (see screenshot enclosed below). If for example I had set the Time Template in my chart to load only 100 bars for the 20 minute interval I would get null also on the external study because it would be returning data only after the first bar of the chart interval
              If you are using a Dynamic Time Template then keep in mind that the chart engine will load whatever amount of bars is necessary to "fill" a chart or 300 bars by default [if those accomplish the task] which is why I used 300 bars in my example
              Alex

              Comment


              • #8
                Hi Alex

                Thanks for the detailed reply.

                Cheers
                Mark

                Comment

                Working...
                X