Announcement

Collapse
No announcement yet.

Verifying over Multiple timeframes

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

  • Verifying over Multiple timeframes

    Like everyone else, I am working towards a trading system that will work successfully for me.

    Here is my latest question.

    I am using the 1 minute and the 5 minute timeframes, and I am looking to identify when stochastics for both timeframes will V up or down (with the K line).

    I realize that when the 5 minute Stoch turn up/down, there is really a 5 minute period when the 1 minute can turn up/down and meet my condition.

    What I am trying to identify through an EFS is that the 1 minute must V up or down within;
    - if 2 - 1 minute periods in order to send an alert
    - if 3 - 1 minute periods, alert to check a different indicator to determine whether or not to enter or ignore this opportunity.

    As my logic is getting more specific, I realize that more challenging programing lies ahead of me, but if anyone knows if this is possible and might know of or have some code I can review, it would be greatly appreciated.
    I have already tried to search for anything like this with no luck.

    Thanks in Advance

    Royce

  • #2
    Hi Royce,

    I put this efs together using the customStoch.efs from the EFS 2 Custom Folder in the eSignal directory.

    I used the two time-frames you mentioned, and added a working structure that you can study to create your trading system. Along with that I added a number of commented out debugPrintln lines that you can un-comment if you want. This may provide help understand the conditional logic if it is not clear. Download tick data and run the efs against it if you want to see the efs run while the market is slow or closed.

    If not familiar with what I am doing, please use the existing debug output (or add some additional ones) to help you figure this out. If you still cannot figure things out after using the debug output and sleeping on it a couple of days, post your questions, either myself or other forum members will try and answer them

    This is a working efs. The long, short and combined testing variables are for demonstration purposes only.

    I hope this will help you out.



    PHP Code:
    /*********************************************************
    By Alexis C. Montenegro for eSignal.  © December 2004       
    Use and/or modify this code freely. If you redistribute it
    please include this and/or any other comment blocks and a 
    description of any changes you make.  

    Modified by S. Hare on 5 8 2008 to add second interval and hard coding 1 and 5 min intervals
    required variable re-naming and creation of additional series.  The function Parameter settings 
    remained the same such that the KLength,KSmoothing,DLength are common parameters across both timeframes
    also added arrays to keep track of data, sections for conditionals, etc.  Everything after the 
    bInit section added, return statement modified
    **********************************************************/

    var fpArray = new Array();

    function 
    preMain() {

        
    setPriceStudy(false);
        
    setStudyTitle("Stochastic");
        
    setCursorLabelName("%K-1",0);
        
    setCursorLabelName("%D-1",1);
        
    setDefaultBarFgColor(Color.blue0);
        
    setDefaultBarFgColor(Color.red1);
        
    setPlotType(PLOTTYPE_LINE,0);
        
    setPlotType(PLOTTYPE_LINE,1);
        
    setDefaultBarThickness(1,0);
        
    setDefaultBarThickness(1,1);
      
        
    setCursorLabelName("%K-5",2);
        
    setCursorLabelName("%D-5",3);
        
    setCursorLabelName("barCount=",4);
        
    setDefaultBarFgColor(Color.blue2);
        
    setDefaultBarFgColor(Color.red3);
        
    setPlotType(PLOTTYPE_LINE,2);
        
    setPlotType(PLOTTYPE_LINE,3);
        
    setDefaultBarThickness(2,2);
        
    setDefaultBarThickness(2,3);
        
    askForInput();
            
        var 
    x=0;
        
    fpArray[x] = new FunctionParameter("KLength"FunctionParameter.NUMBER);
     
    with(fpArray[x++]){
            
    setName("%K");
            
    setLowerLimit(1);  
            
    setDefault(14);
        }
     
    fpArray[x] = new FunctionParameter("KSmoothing"FunctionParameter.NUMBER);
     
    with(fpArray[x++]){
            
    setName("%KSmooth");
            
    setLowerLimit(1);  
            
    setDefault(1);
        }
        
    fpArray[x] = new FunctionParameter("DLength"FunctionParameter.NUMBER);
     
    with(fpArray[x++]){
            
    setName("%D");
            
    setLowerLimit(1);  
            
    setDefault(3);
        }
        
    fpArray[x] = new FunctionParameter("Symbol"FunctionParameter.STRING);
        
    with(fpArray[x++]){
            
    setDefault();
     }
     
    fpArray[x] = new FunctionParameter("Interval"FunctionParameter.STRING);
     
    with(fpArray[x++]){
            
    setDefault();
        }
        
    fpArray[x] = new FunctionParameter("Upper"FunctionParameter.NUMBER);
     
    with(fpArray[x++]){
            
    setLowerLimit(0);
            
    setDefault(80); 
        }
     
    fpArray[x] = new FunctionParameter("Lower"FunctionParameter.NUMBER);
     
    with(fpArray[x++]){
            
    setLowerLimit(0);
            
    setDefault(20); 
     }
     
    fpArray[x] = new FunctionParameter("Params"FunctionParameter.BOOLEAN);
     
    with(fpArray[x++]){
            
    setName("Show Parameters");
            
    setDefault(false);
        }
    }

    var 
    bInit false;
    var 
    x1StochK null;
    var 
    x1StochD null;
    var 
    x5StochK null;
    var 
    x5StochD null;

    var 
    k1=[null,null,null,null,null]; //~ legal JavaScript Array declaration shortcut, null filled, length = 5
    var d1=[null,null,null,null,null];
    var 
    k5=[null,null,null,null,null];
    var 
    d5=[null,null,null,null,null];

    var 
    n1State=null;
    var 
    n5State=null;

    var 
    n1Inv="1";
    var 
    n5Inv="5";
    var 
    dInit=false;

    var 
    stoch1_LongTest=[null,null,null,null,null];
    var 
    stoch1_ShortTest=[null,null,null,null,null];
    var 
    stoch5_LongTest=[null,null,null,null,null];
    var 
    stoch5_ShortTest=[null,null,null,null,null];
    var 
    condition_LongTest=[null,null,null,null,null];
    var 
    condition_ShortTest=[null,null,null,null,null];

    debugClear();

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

     if(
    bInit == false){
      if(
    Symbol == nullSymbol getSymbol();
      
    //~ if(Interval == null) Interval = getInterval();
      
    var vSymbol1 Symbol+","+n1Inv;
      var 
    vSymbol5 Symbol+","+n5Inv;
      
    x1StochK stochK(KLength,KSmoothing,DLength,sym(vSymbol1));
      
    x1StochD stochD(KLength,KSmoothing,DLength,sym(vSymbol1));
      
      
    x5StochK stochK(KLength,KSmoothing,DLength,sym(vSymbol5));
      
    x5StochD stochD(KLength,KSmoothing,DLength,sym(vSymbol5));
      
    addBandUpperPS_SOLID1Color.black,"Upper");
      
    addBandLowerPS_SOLID1Color.black,"Lower");

      
    bInit true;
     }
      
     
    n1State getBarStateInterval(n1Inv);
     
    n5State getBarStateInterval(n5Inv);
     var 
    barCount=getCurrentBarCount();

     
    //~ check for valid data and create an array from values returned from each series
     
    if(dInit == false){
      if((
    k1[0])&&(d1[0])&&(k5[0])&&(d5[0])){ // nulls evalute to false
       
    dInit=true;
       
    debugPrintln("137: first bar that all variables are defined is bar number "+barCount);debugPrintln(" ");
       
    debugPrintln("138: k1 = ["+k1+"], array length = "+k1.length);
       
    debugPrintln("139: d1 = ["+d1+"], array length = "+d1.length);
       
    debugPrintln("140: k5 = ["+k5+"], array length = "+k5.length);
       
    debugPrintln("141: d5 = ["+d5+"], array length = "+d5.length);debugPrintln("");
      }
     }
     

     var 
    tempK1=x1StochK.getValue(0);
     var 
    tempD1=x1StochD.getValue(0);
     var 
    tempK5=x5StochK.getValue(0);
     var 
    tempD5=x5StochD.getValue(0);
     var 
    lastBarOnChart=isLastBarOnChart(); 
     
     var 
    testFlag,testFlag1,testFlag5// declaring multiple variables like this is acceptable in JavaScript
     
    testFlag=testFlag1=testFlag5=false// see note
     
     //~ Note: variables can be set to simple datatypes like string, number, and boolean without them being 'referenced' to each other.  
     //~ This means that modification of their value will not affect the other variables.  This is not the case with datatype 
     //~  objects (Arrays and Series objects) which if set like this would point to the same object, and all would change if you only changed one.  
     
     
    if(n1State==BARSTATE_NEWBAR){ 
      
    //~ debugPrintln(""); debugPrintln("160: k1 = ["+k1+"], array length = "+k1.length+", isLastBarOnChart()= "+lastBarOnChart);
      
    k1.unshift(tempK1);
      
    //~ debugPrintln("162: k1 = ["+k1+"], array length = "+k1.length);
      
    k1.pop();
      
    d1.unshift(tempD1);
      
    d1.pop();
      
    testFlag=testFlag1=dInit;
      
    //~ debugPrintln("167: (n1State==BARSTATE_NEWBAR), barCount = "+barCount);
     
    }
     else{
      
    //~ debugPrintln("170: k1 = ["+k1+"], array length = "+k1.length+", isLastBarOnChart()= "+lastBarOnChart);
      
    k1[0]=tempK1;
      
    //~ debugPrintln("172: k1 = ["+k1+"], array length = "+k1.length+", isLastBarOnChart()= "+lastBarOnChart);
      
    d1[0]=tempD1;
     }
     
     if(
    n5State==BARSTATE_NEWBAR){ 
      
    k5.unshift(tempK5);k5.pop();
      
    d5.unshift(tempD5);d5.pop();
      
    testFlag=testFlag5=dInit;
      
    //~ debugPrintln("180: (n5State==BARSTATE_NEWBAR), barCount = "+barCount); debugPrintln("");
      
     
    }
     else{ 
      
    k5[0]=tempK5;
      
    d5[0]=tempD5;
     }
     
     if(
    testFlag==true){
      if(
    testFlag5==true){ //~  Included copies of identical conditionals to demonstrate the short and long test array
       //~ put your conditionals in here for your 5 minute conditionals
       
       
    stoch5_LongTest[0]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false 
       
    stoch5_LongTest[1]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false
       
    stoch5_LongTest[2]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false
      
       
    stoch5_ShortTest[0]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false 
       
    stoch5_ShortTest[1]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false 
       
    stoch5_ShortTest[2]=((k5[1]<k5[2])&&(k5[2]>k5[3])); //~ either true or false 
       
       //~ the arrays are k5 and d5 and for this example, the length of each array is 5.  Array's are always zero indexed
       //~ and the index values are psitive numbers, eg 0,1,2,3,4.  As a practical matter, when testing values returned from indicators, 
       //~ I recommend using the second index (and older) values contained in the arrays, k5[1] , d5[1], k5[2] , d5[2], etc.  
         
       //~ A common problem when developing trading systems is what I refer to as 'future vision' and it can be a difficult concept 
       //~ to pick up.  This happens because as historical data is loaded onto the chart, the calculations for the current bar
       //~ are  based on prices that were unknown in real time until after the expiration of the current bar (the first 
       //~ tick of the next bar specifically). This can result in seemingly tremendous strategies by trading the current bar 
       //~ with a seemingly perfect indicator.  This can result in trading the current bar price range with an indicator that 
       //~ was calculated at the beginning of the next bar, the effect being that you are seeing into the future by one bar. 

       //~ It is certainly possible to create a trading system that evaluates the zero index of a calculated indicator with 
       //~ historical data.  The indicator calculations can readily be compared, eg if((k5[0]<k5[1])&&(k5[1]>k5[2])){etc..}.  
       //~ However, you must be careful to use prices from the previous bar {high(-1), low(-1), close(-1)} or the open(0) of
       //~ the current bar.  Determining correct trade prices and ensuring you are not trading with 'future-vision' are 
       //~ critical whenever you use the Strategy Analyzer or similar tool to evaluate your trading system's success.
       //~ The adage garbage-in, garbage out is definitely the rule here, not the exception.  To use a tool such as the Strategy
       //~ Analyzer, don't think the tool reads your mind, rather it does only what you tell it to do and assumes you know what 
       //~ you are doing.  

       //~ Transitioning a trading system to work with both historical and live data can be quite difficult , especially if you
       //~ created it to evaluate the zero index of a calculated indicator when processing historical data. With live data, the zero index is the
       //~ value of the indicator calculated at each tick contained in the bar, always slightly different.  More often than not, the indicator calc 
       //~ from the first tick of a new bar is identical to the indicator calculated on the last tick (close) of the previous bar (k5[0] == k5[1]).
       //~ Now the indicator calculations with live data are different, and the conditional in the previous example will not work as before.  
       //~ Evaluating this conditional once per bar will no longer get the same results as were obtained while loading historical
       //~ data.  The equivalent conditional (live) now becomes ==>>  if((k5[1]<k5[2])&&(k5[2]>k5[3])){etc..} If you plan to modify your code 
       //~ to behave differently for historical and live data, you will not only have to figure out when to change from one to the other, but will 
       //~ also increase the number of the conditionals in your system and significantly increase the complexity. 

       //~ To get around these complexities, it is best to use the same conditionals for historical and live data.  Therefore, I recommend that when 
       //~ starting trading system development, stay away from evaluating the zero index of a calculated indicator with either
       //~ historical or live data.  The example conditional would not evaluate the zero index of the indicator array, (k5[0],d5[0]) and 
       //~ would look like this The equivalent conditional (live) now becomes ==>>  if((k5[1]<k5[2])&&(k5[2]>k5[3])){etc..}  You still must be careful 
       //~ to use appropriate historical prices, but now you can use values from the current bar {high(0), low(0), close(), open(0)}.  Not only is the 
       //~ likelyhood of 'future vision' significantly reduced, but when applied appropriatley, allows for more realistic results from the Strategy Analyzer 
       //~ and more flexibility when using stops and limit trades.  The adage garbage-in, garbage out is still true, but a simpler system will only help
      
      
    }
      
      if(
    testFlag1==true){//~  Included copies of identical conditionals to demonstrate the short and long test array
      
       //~ the arrays are k1 and d1 and for this example, the length of each array is 5.  Array's are always zero indexed
       //~ and the index values are psitive numbers, eg 0,1,2,3,4.  As a practical matter, when testing values returned from indicators, use the second 
       //~ (and older) index of the arrays, k1[1] , d1[1], k1[2] , d1[2], etc.
       
       
    stoch1_LongTest[0]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false 
       
    stoch1_LongTest[1]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false
       
    stoch1_LongTest[2]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false
      
       
    stoch1_ShortTest[0]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false 
       
    stoch1_ShortTest[1]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false 
       
    stoch1_ShortTest[2]=((k1[1]<k1[2])&&(k1[2]>k1[3])); //~ either true or false 
      
      
    }
     
      
    //~ put your combined conditionals in here that compare conditionals from both time frames
      //~ notice the conditionals are not part of an if statement, rather the result of the conditional is assigned to 
      //~ variables which can be combined and tested later
      
      
    condition_LongTest[0]= (stoch1_LongTest[0]&&stoch1_LongTest[1]&&stoch1_LongTest[2]);
      
    condition_LongTest[1]= (stoch5_LongTest[0]&&stoch5_LongTest[1]&&stoch5_LongTest[2]);
      
    condition_ShortTest[0]=(stoch1_ShortTest[0]&&stoch1_ShortTest[1]&&stoch1_ShortTest[2]);
      
    condition_ShortTest[1]=(stoch5_ShortTest[0]&&stoch5_ShortTest[1]&&stoch5_ShortTest[2]);
      
      if(
    condition_LongTest[0]&&condition_LongTest[1]){/*  do something */}
      if(
    condition_ShortTest[0]&&condition_ShortTest[1]){/*  do something else*/}
     
     }
     
     
    barCount=""+barCount//~ converting number to a string

     //~ look at the last barCount variable added to the return statement below, since it is a string, it is shown in the cursor window 
     //~ versus the chart.  Including the barcount is a helper I use while scrolling through the chart 
      
    return new Array (getSeries(x1StochK),getSeries(x1StochD),getSeries(x5StochK),getSeries(x5StochD),barCount);
    }

    function 
    postMain(){
     
    bInit=dInit=false;

    Attached Files

    Comment


    • #3
      stevehare2003

      I don't even know how to begin to thank you for the amount of work and effort you must have put into preparing this response. I have just read your post and will be working feverishly with it to see if I can (1) get my head around the code and (2) mold it into a usable format to meet my needs.
      Although I am no where near claiming victory, thank you again for the time and effort invested, it is greatly appreciated.

      Sincerely,

      Royce

      Comment


      • #4
        Hi Royce,

        You are most welcome.

        As you go through the code and follow the debug statements, be aware that the more debug output which accumulates in the Formula Output Window will have a negative effect on performance.

        The impact on performance is why I use a debugClear() command in the code. Don't worry that you will miss any output when this window is cleared. The debug output not only goes to the Formula Output Window, it is also saved in this file C:\Program Files\eSignal\formulaoutput.log, and is unaffected by the debugClear() command. I've found that creating a shortcut to this file is very handy.

        Comment

        Working...
        X