Announcement

Collapse
No announcement yet.

Help for MA crossovers

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

  • Help for MA crossovers

    Hello

    I am trying to write an efs for the following system of 4 moving averages with alert sounds for different situations.

    A 3 and 5 period MA based on HLC/3 and an 8 period MA based on the High and a 10 period MA based on the Low.

    1. When the 3 is above the 5 and both are above the 8 – sound an alert and when the 3 moves below the 5 while both still remaining above the 8 – sound an alert.

    2. When the 3 is below the 5 when both are below the 10 – sound an alert and when the 3 moves above the 5 whilst both are still below the 10 –sound an alert.

    3. When the 3 and the 5 are between the 8 and the 10 – also sound an alert. The relative order of the 3 & 5 when they are between the 8 and 10 is unimportant – only the fact that both are between the 8 & 10.

    I have used Alexis’ ‘basicmax2(alert)’ as the basis for this purpose. I have not written any efs before except for some small cut and paste jobs. This is my first attempt at writing conditionals and statements and they could look rather clumsy and inefficient. I have used different sound alerts to check if the lines work. I know some do and some don’t –even if clumsily. I will adjust the number and type of sound alerts when the efs works properly.

    Ideally I would like the alerts to sound only the first time when there are changes and then sound again when the condition changes [i.e., no alerts while the same condition continues] but that seems to be way over my head. As it stands the alerts sound on every bar.

    My code is attached and I would appreciate any help from members and especially if Alexis has the time to cast his expert eye over my clumsy effort.

    Thanks
    Attached Files

  • #2
    charttrader
    The conditions in your script don't quite match the logic that you laid out in plain language.
    To accomplish what you are trying to do you would need to make the following changes.
    As a first step declare a global variable [ie outside of the preMain() or main() functions] called vFlag2 and set it initially to 0 eg
    PHP Code:
    var vFlag2 0
    Then add the following lines of code after line 186 of your script
    PHP Code:
        var ma3  vMA1.getValue(MAStudy.MA);//value of vMA1 at current bar
        
    var ma3prev vMA1.getValue(MAStudy.MA,-1);//value of vMA1 at previous bar
        
    var ma5  vMA2.getValue(MAStudy.MA);//value of vMA2 at current bar
        
    var ma5prev vMA2.getValue(MAStudy.MA,-1);//value of vMA2 at previous bar
        
    var ma8  vMA3.getValue(MAStudy.MA);//etc
        
    var ma10 vMA4.getValue(MAStudy.MA); 
    These lines of code are used to assign to local variables the values of the averages at the current and/or prior bars (the latter are necessary to determine the cross overs). Besides being a more efficient way of writing code creating these variables makes it easier to write the conditions to trigger the alerts.
    Then replace lines 188-232 of your script with the following (comments are included in the code)
    PHP Code:
        if(vFlag ==0){
            if(
    ma3>ma8 && ma5>ma8 && ma3prev>ma5prev && ma3<ma5){
            
    //IF ma3 and ma5 are above ma8 AND ma3 crosses below ma5 THEN
                
    Alert.playSound("doorbell.wav");//play sound
                
    vFlag 1;//set vFlag to 1
                
    vFlag2 0;//set vFlag2 to 0
            
    }
            else if(
    ma3<ma10 && ma5<ma10 && ma3prev<ma5prev && ma3>ma5){
            
    //IF ma3 and ma5 are below ma10 AND ma3 crosses above ma5 THEN
                
    Alert.playSound("buzzer.wav");
                
    vFlag 1;
                
    vFlag2 0;
            }
            else if(
    ma3>ma10 && ma3<ma8 && ma5>ma10 && ma5<ma8){
            
    //If ma3 and ma5 are above ma10 AND below ma8 THEN
                
    if(vFlag2!=1){
                
    //IF vFlag2 is not equal to 1 THEN (this check prevents multiple alerts inside the channel)
                    
    Alert.playSound("bullet.wav");
                    
    vFlag 1;
                    
    vFlag2 1;
                }
            }
        } 
    Once you make these changes you should get a single alert per bar when any one condition evaluates to true.
    In the case of the 3 and 5 averages crossing when above the 8 or below the 10 you may get more than one alert per side (not per bar) in as much as they could be crossing multiple times while both are above the 8 or below the 10. When the 3 and 5 are inside the channel instead you will only get one alert. In order to get another alert within the channel one of the other two conditions needs to evaluate to true.
    If you are interested in learning how to program in EFS I would suggest that you begin by reviewing the JavaScript for EFS video series and the Core JavaScript Reference Guide. Those will provide you with a thorough introduction to programming in JavaScript which is at the foundation of EFS. Then go through the EFS KnowledgeBase and study the Help Guides and Tutorials which will provide you with the specifics of EFS.
    Alex


    Originally posted by charttrader
    Hello

    I am trying to write an efs for the following system of 4 moving averages with alert sounds for different situations.

    A 3 and 5 period MA based on HLC/3 and an 8 period MA based on the High and a 10 period MA based on the Low.

    1. When the 3 is above the 5 and both are above the 8 – sound an alert and when the 3 moves below the 5 while both still remaining above the 8 – sound an alert.

    2. When the 3 is below the 5 when both are below the 10 – sound an alert and when the 3 moves above the 5 whilst both are still below the 10 –sound an alert.

    3. When the 3 and the 5 are between the 8 and the 10 – also sound an alert. The relative order of the 3 & 5 when they are between the 8 and 10 is unimportant – only the fact that both are between the 8 & 10.

    I have used Alexis’ ‘basicmax2(alert)’ as the basis for this purpose. I have not written any efs before except for some small cut and paste jobs. This is my first attempt at writing conditionals and statements and they could look rather clumsy and inefficient. I have used different sound alerts to check if the lines work. I know some do and some don’t –even if clumsily. I will adjust the number and type of sound alerts when the efs works properly.

    Ideally I would like the alerts to sound only the first time when there are changes and then sound again when the condition changes [i.e., no alerts while the same condition continues] but that seems to be way over my head. As it stands the alerts sound on every bar.

    My code is attached and I would appreciate any help from members and especially if Alexis has the time to cast his expert eye over my clumsy effort.

    Thanks

    Comment


    • #3
      Hi Alex

      Thank you very much for correcting my script. The script appears to be working nicely. However there are three little tweaks that I would like to make with your assistance to reflect the situation I have in mind.

      First tweak:
      Your coding has taken care of the second part of the conditions listed in number 1 of my idea i.e. – ‘when the 3 moves below the 5 while both still remaining above the 8 – sound an alert’.
      The first part of the condition [in number 1] - I am sorry I was not more explicit in my writing. This should have been ‘when the 3 is above the 5 and both are above the 8’ AND the 3 is still above [continues to be] the 5 – sound an alert. The difference between this first part and the second part [which is in your code] is subtle but is important.

      Second tweak:
      The same is applicable to the first part of the conditions listed in number 2. This should have been ‘when the 3 is below the 5 when both are [still] below the 10 AND the 3 is still below [continues to be] below the 5 – sound an alert. The difference between this first part and the second part [again already coded by you] is also subtle.
      I think I could have had all these in mind in my crude script and this is perhaps the main reason for your comment that ‘the conditions in your script do not seem to quite match the logic that you laid out in plain language.’ I apologise for the loose manner of plain writing as compared to the precise requirement of efs coding.

      Third tweak:
      You said ‘when the 3 and 5 are inside the channel instead you will only get one alert.[pefectly OK] In order to get another alert within the channel one of the other two conditions needs to evaluate to true’.
      Instead of waiting for one of the other two conditions to evaluate to true, would it be possible to sound an alert [once only until there is another change] when both the 3 and the 5 [as a pair] either move above the 8 or move below the 10 from within the channel of the 8 and 10.

      Using your efs coding as a guide I have attempted to put the first parts of both sections as additional lines in the corrected script you have set out in your reply. I shall be most grateful if you could look it over for any possible errors even though the whole script could appear to be working.

      Now that I have taken my first steps in learning to program in efs I shall most certainly follow your suggestions about reviewing the available material on this subject. A preliminary review indicates there is a huge amount of stuff to read and understand.
      Once again thanks very much for your much appreciated help.

      if(vFlag ==0){

      if(ma3>ma8 && ma5>ma8 && ma3prev<ma5prev && ma3>ma5){

      //IF ma3 and ma5 are above ma8 AND ma3 crosses above ma5 THEN

      Alert.playSound("phone.wav");//play sound

      vFlag = 1;//set vFlag to 1

      vFlag2 = 0;//set vFlag2 to 0

      }


      else if(ma3>ma8 && ma5>ma8 && ma3prev>ma5prev && ma3<ma5){

      //IF ma3 and ma5 are above ma8 AND ma3 crosses below ma5 THEN

      Alert.playSound("doorbell.wav");//play sound

      vFlag = 1;//set vFlag to 1

      vFlag2 = 0;//set vFlag2 to 0

      }

      else if(ma3<ma10 && ma5<ma10 && ma3prev>ma5prev && ma3<ma5){

      //IF ma3 and ma5 are below ma10 AND ma3 crosses below ma5 THEN

      Alert.playSound("Yea.wav");

      vFlag = 1;

      vFlag2 = 0;

      }


      else if(ma3<ma10 && ma5<ma10 && ma3prev<ma5prev && ma3>ma5){

      //IF ma3 and ma5 are below ma10 AND ma3 crosses above ma5 THEN

      Alert.playSound("buzzer.wav");

      vFlag = 1;

      vFlag2 = 0;

      }



      else if(ma3>ma10 && ma3<ma8 && ma5>ma10 && ma5<ma8){

      //If ma3 and ma5 are above ma10 AND below ma8 THEN

      if(vFlag2!=1){

      //IF vFlag2 is not equal to 1 THEN (this check prevents multiple alerts inside the channel)

      Alert.playSound("bullet.wav");

      vFlag = 1;

      vFlag2 = 1;

      }

      }

      }

      Comment


      • #4
        here's my attempt based on what I understand you've been describing...

        not sure what instrument or time frame you're using, I'm trying AAPL on a 1-min.

        I've added different colored squares at the alerts so you can "see on-screen" if it's doing what you expect.

        I haven't reviewed the vFlags given by Alex. also, still learning about the subtle changes the presence of "else" can create

        p.s. you'll notice when the 3 and 5 cross, they almost always cross back between the bands, so that alert doesn't seem to go off very often...

        PHP Code:
            setPriceStudy(true);
            
        setStudyTitle("PivotMA&BandSystemR7");

            
        setCursorLabelName("MA-3"0);
            
        setCursorLabelName("MA-5"1);   
            
        setCursorLabelName("MA-8"2);
            
        setCursorLabelName("MA-10"3);
            
                
            
        setDefaultBarStyle(PS_SOLID0);
            
        setDefaultBarStyle(PS_SOLID1);
            
        setDefaultBarStyle(PS_DASH2);
            
        setDefaultBarStyle(PS_DASH3); 
            

            
        setDefaultBarFgColor(Color.blue0);
            
        setDefaultBarFgColor(Color.red1);
            
        setDefaultBarFgColor(Color.brown2);
            
        setDefaultBarFgColor(Color.navy3);
            
            
            
        setDefaultBarThickness(20);
            
        setDefaultBarThickness(21);
            
        setDefaultBarThickness(12);
            
        setDefaultBarThickness(13);
            

            
        setPlotType(PLOTTYPE_LINE0);
            
        setPlotType(PLOTTYPE_LINE1);    
            
        setPlotType(PLOTTYPE_LINE2);
            
        setPlotType(PLOTTYPE_LINE3);
            
            
           
            
            
           
            var 
        fp1 = new FunctionParameter("MA1Length"FunctionParameter.NUMBER);
            
        fp1.setLowerLimit(1);        
            
        fp1.setDefault(3); //Edit this value to set a new default
            
            
        var fp2 = new FunctionParameter("MA1Offset"FunctionParameter.NUMBER);
            
        fp2.setDefault(0); //Edit this value to set a new default
            
            
        var fp3 = new FunctionParameter("MA1Source"FunctionParameter.STRING);
            
        fp3.setName("MA1Source");
            
        fp3.addOption("Close");
            
        fp3.addOption("High");
            
        fp3.addOption("Low");
            
        fp3.addOption("Open");
            
        fp3.addOption("HL/2");
            
        fp3.addOption("HLC/3");
            
        fp3.addOption("OHLC/4");
            
        fp3.setDefault("HLC/3"); //Edit this value to set a new default     
            
            
        var fp4 = new FunctionParameter("MA1Type"FunctionParameter.STRING);
            
        fp4.setName("MA1Type");
            
        fp4.addOption("MAStudy.SIMPLE");
            
        fp4.addOption("MAStudy.EXPONENTIAL");
            
        fp4.addOption("MAStudy.WEIGHTED");
            
        fp4.addOption("MAStudy.VOLUMEWEIGHTED");
            
        fp4.setDefault("MAStudy.SIMPLE"); //Edit this value to set a new default
            
            
            
        var fp5 = new FunctionParameter("MA2Length"FunctionParameter.NUMBER);
            
        fp5.setLowerLimit(1);        
            
        fp5.setDefault(5); //Edit this value to set a new default
            
            
        var fp6 = new FunctionParameter("MA2Offset"FunctionParameter.NUMBER);
            
        fp6.setDefault(0); //Edit this value to set a new default
            
            
        var fp7 = new FunctionParameter("MA2Source"FunctionParameter.STRING);
            
        fp7.setName("MA2Source");
            
        fp7.addOption("Close");
            
        fp7.addOption("High");
            
        fp7.addOption("Low");
            
        fp7.addOption("Open");
            
        fp7.addOption("HL/2");
            
        fp7.addOption("HLC/3");
            
        fp7.addOption("OHLC/4");
            
        fp7.setDefault("HLC/3"); //Edit this value to set a new default
            
            
        var fp8 = new FunctionParameter("MA2Type"FunctionParameter.STRING);
            
        fp8.setName("MA2Type");
            
        fp8.addOption("MAStudy.SIMPLE");
            
        fp8.addOption("MAStudy.EXPONENTIAL");
            
        fp8.addOption("MAStudy.WEIGHTED");
            
        fp8.addOption("MAStudy.VOLUMEWEIGHTED");
            
        fp8.setDefault("MAStudy.SIMPLE"); //Edit this value to set a new default


            
        var fp9 = new FunctionParameter("MA3Length"FunctionParameter.NUMBER);
            
        fp9.setLowerLimit(1);        
            
        fp9.setDefault(8); //Edit this value to set a new default
            
            
        var fp10 = new FunctionParameter("MA3Offset"FunctionParameter.NUMBER);
            
        fp10.setDefault(0); //Edit this value to set a new default
            
            
        var fp11 = new FunctionParameter("MA3Source"FunctionParameter.STRING);
            
        fp11.setName("MA3Source");
            
        fp11.addOption("Close");
            
        fp11.addOption("High");
            
        fp11.addOption("Low");
            
        fp11.addOption("Open");
            
        fp11.addOption("HL/2");
            
        fp11.addOption("HLC/3");
            
        fp11.addOption("OHLC/4");
            
        fp11.setDefault("High"); //Edit this value to set a new default
            
            
        var fp12 = new FunctionParameter("MA3Type"FunctionParameter.STRING);
            
        fp12.setName("MA3Type");
            
        fp12.addOption("MAStudy.SIMPLE");
            
        fp12.addOption("MAStudy.EXPONENTIAL");
            
        fp12.addOption("MAStudy.WEIGHTED");
            
        fp12.addOption("MAStudy.VOLUMEWEIGHTED");
            
        fp12.setDefault("MAStudy.SIMPLE"); //Edit this value to set a new default


            
        var fp13 = new FunctionParameter("MA4Length"FunctionParameter.NUMBER);
            
        fp13.setLowerLimit(1);        
            
        fp13.setDefault(10); //Edit this value to set a new default
            
            
        var fp14 = new FunctionParameter("MA4Offset"FunctionParameter.NUMBER);
            
        fp14.setDefault(0); //Edit this value to set a new default
            
            
        var fp15 = new FunctionParameter("MA4Source"FunctionParameter.STRING);
            
        fp15.setName("MA4Source");
            
        fp15.addOption("Close");
            
        fp15.addOption("High");
            
        fp15.addOption("Low");
            
        fp15.addOption("Open");
            
        fp15.addOption("HL/2");
            
        fp15.addOption("HLC/3");
            
        fp15.addOption("OHLC/4");
            
        fp15.setDefault("Low"); //Edit this value to set a new default
            
            
        var fp16 = new FunctionParameter("MA4Type"FunctionParameter.STRING);
            
        fp16.setName("MA4Type");
            
        fp16.addOption("MAStudy.SIMPLE");
            
        fp16.addOption("MAStudy.EXPONENTIAL");
            
        fp16.addOption("MAStudy.WEIGHTED");
            
        fp16.addOption("MAStudy.VOLUMEWEIGHTED");
            
        fp16.setDefault("MAStudy.SIMPLE"); //Edit this value to set a new default

            
        }

        var 
        vFlag 0;

        function 
        main(MA1Length,MA1Offset,MA1Source,MA1Type,MA2Length,MA2Offset,MA2Source,MA2Type,MA3Length,MA3Offset,MA3Source,MA3Type,MA4Length,MA4Offset,MA4Source,MA4Type){ //MA5Length,MA5Offset,MA5Source,MA5Type) {

            
        if (vMA1 == nullvMA1 = new MAStudy(MA1LengthMA1OffsetMA1Source, eval(MA1Type));
            if (
        vMA2 == nullvMA2 = new MAStudy(MA2LengthMA2OffsetMA2Source, eval(MA2Type));
            if (
        vMA3 == nullvMA3 = new MAStudy(MA3LengthMA3OffsetMA3Source, eval(MA3Type));
            if (
        vMA4 == nullvMA4 = new MAStudy(MA4LengthMA4OffsetMA4Source, eval(MA4Type));
            
             

        /*****************************************
        Insert your code following this text block
        Use vMA1.getValue(MAStudy.MA) and         
        vMA2.getValue(MAStudy.MA) for your code   
        ******************************************/

         
        if(getBarState()==BARSTATE_NEWBAR){
         
        vFlag 0;
         
         }
         var 
        ma3  vMA1.getValue(MAStudy.MA);//value of vMA1 at current bar
            
        var ma3prev vMA1.getValue(MAStudy.MA,-1);//value of vMA1 at previous bar
            
        var ma5  vMA2.getValue(MAStudy.MA);//value of vMA2 at current bar
            
        var ma5prev vMA2.getValue(MAStudy.MA,-1);//value of vMA2 at previous bar
            
        var ma8  vMA3.getValue(MAStudy.MA);//etc
            
        var ma8prev  vMA3.getValue(MAStudy.MA,-1);//etc
            
        var ma10 vMA4.getValue(MAStudy.MA);
            var 
        ma10prev vMA4.getValue(MAStudy.MA,-1);
            
        if(
        vFlag ==0){

                if( 
        ma3>ma8 && 
                    
        ma5>ma8 && 
                    (
        ma3prev<ma8prev ||
                    
        ma5prev<ma8prev) && 
                    
        ma3>ma5
                
        ){
                
        //1a.)  IF ma3 above ma8, ma5 above ma8 - either previously being below ma8
                //      AND ma3 above ma5 THEN
                    
        drawShapeRelative(030Shape.SQUARE""Color.blueShape.RELATIVETOTOP,"1"+rawtime(0));
                    
        Alert.playSound("phone.wav");//play sound
                    
        vFlag 1;//set vFlag to 1
                    
        vFlag2 0;//set vFlag2 to 0
                
        }

                else 
                if( 
        ma3>ma8 && 
                    
        ma5>ma8 && 
                    
        ma3prev>ma5prev && 
                    
        ma3<ma5
                
        ){
                
        //1b.) IF ma3 and ma5 are above ma8 
                //     AND ma3 crosses below ma5 THEN
                    
        drawShapeRelative(030Shape.SQUARE""Color.cyanShape.RELATIVETOTOP,"2"+rawtime(0));
                    
        Alert.playSound("doorbell.wav");//play sound
                    
        vFlag 1;//set vFlag to 1
                    
        vFlag2 0;//set vFlag2 to 0
                
        }

                else 
                if( 
        ma3<ma10 && 
                    
        ma5<ma10 && 
                    (
        ma3prev>ma10prev ||
                    
        ma5prev>ma10prev) && 
                    
        ma3<ma5
                
        ){
                
        //2a.)  IF ma3 below ma10, ma5 below ma10 - either previously being above ma10 
                //      AND ma3 below ma5 THEN
                    
        drawShapeRelative(030Shape.SQUARE""Color.redShape.RELATIVETOTOP,"3"+rawtime(0));
                    
        Alert.playSound("Yea.wav");
                    
        vFlag 1;
                    
        vFlag2 0;
                }

                else 
                if( 
        ma3<ma10 && 
                    
        ma5<ma10 && 
                    
        ma3prev<ma5prev && 
                    
        ma3>ma5){
                
        //2b.)  IF ma3 and ma5 are below ma10 
                //      AND ma3 crosses above ma5 THEN
                    
        drawShapeRelative(030Shape.SQUARE""Color.magentaShape.RELATIVETOTOP,"4"+rawtime(0));
                    
        Alert.playSound("buzzer.wav");
                    
        vFlag 1;
                    
        vFlag2 0;
                }

                else 
                if( 
        ma3>ma10 && 
                    
        ma3<ma8 && 
                    
        ma5>ma10 && 
                    
        ma5<ma8
                
        ){
                
        //If ma3 and ma5 are above ma10 AND below ma8 THEN
                
        if(vFlag2!=1){
                    
        //IF vFlag2 is not equal to 1 THEN (this check prevents multiple alerts inside the channel)
                    
        drawShapeRelative(030Shape.SQUARE""Color.greenShape.RELATIVETOTOP,"5"+rawtime(0));
                    
        Alert.playSound("bullet.wav");
                    
        vFlag 1;
                    
        vFlag2 1;
                    }
                }
        }    
            
        /*
        if(vFlag ==0){
                if(ma3>ma8 && ma5>ma8 && ma3prev>ma5prev && ma3<ma5){
                //1.) IF ma3 and ma5 are above ma8 AND ma3 crosses below ma5 THEN
                drawShapeRelative(0, 30, Shape.SQUARE, "", Color.blue, Shape.RELATIVETOTOP,"1"+rawtime(0));
                
                    Alert.playSound("doorbell.wav");//play sound
                    vFlag = 1;//set vFlag to 1
                    vFlag2 = 0;//set vFlag2 to 0
                }
                else if(ma3<ma10 && ma5<ma10 && ma3prev<ma5prev && ma3>ma5){
                //2.) IF ma3 and ma5 are below ma10 AND ma3 crosses above ma5 THEN
                drawShapeRelative(0, 30, Shape.SQUARE, "", Color.green, Shape.RELATIVETOTOP,"2"+rawtime(0));
                
                    Alert.playSound("buzzer.wav");
                    vFlag = 1;
                    vFlag2 = 0;
                }
                else if(ma3>ma10 && ma3<ma8 && ma5>ma10 && ma5<ma8){
                //If ma3 and ma5 are above ma10 AND below ma8 THEN
                    if(vFlag2!=1){
                    //IF vFlag2 is not equal to 1 THEN (this check prevents multiple alerts inside the channel)
                    drawShapeRelative(0, 30, Shape.SQUARE, "", Color.maroon, Shape.RELATIVETOTOP,"3"+rawtime(0));
                
                        Alert.playSound("bullet.wav");
                        vFlag = 1;
                        vFlag2 = 1;
                    }
                }
            }
        */

        return new Array (vMA1.getValue(MAStudy.MA), vMA2.getValue(MAStudy.MA),vMA3.getValue(MAStudy.MA), vMA4.getValue(MAStudy.MA)); 

        Attached Files
        Last edited by zeller4; 01-12-2008, 07:43 AM.

        Comment


        • #5
          Hello zeller4

          Thank you very much for your help. I have placed your code in a chart post haste and it is working. I need to look at all the coloured squares with the different sound alerts to check if the result is what I am trying to achieve. Will try to reduce the different alert sounds to make it less confusing eventually. Initially everything seems to be turning out correctly. Your idea of plotting the coloured squares for visual checks is fantastic. My compliments to you.

          The efs is the bare bones of a system to be used for index futures trading on a 5 minute chart. This is the intention but will have to check on suitability on other time frames.

          I will be following up on learning as much as I am able or can about how to program in efs. Once again thank you so much for your help.

          Robert

          Comment


          • #6
            Robert,

            You're welcome. I'm typically trading AB #F so I'll try it with that. If you see some other index instruments you use or some different rules, I appreciate your sharing.

            Glad to help. I'm constantly learning new coding techniques myself. I wish you success with the tutorials and writing / modifying code.

            Kirk

            Comment

            Working...
            X