Announcement

Collapse
No announcement yet.

Simple Button

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

  • Simple Button

    I'm trying to create a toggle button on my chart to allow or dis-allow code processing. But I can't get it to toggle.
    PHP Code:
    debugClear();
    var 
    flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;
    ButtonTitle "Enable"
    backcolor Color.yellow;
    forcolor Color.blue;
    ButtonPressed=null;
    enable false;

    function 
    preMain(){
        
    setPriceStudy(true);
    }

    function 
    toggle(){
        
    Alert.playSound("click.wav");
        if ( 
    ButtonPressed ==  BUTTON_LEFT) {
            if (
    ButtonTitle "Disable"){
                
    ButtonTitle "Enable";
                
    enable=false;
            } else if(
    ButtonTitle "Enable"){  // current state is disabled 
                
    ButtonTitle "Disable";
                
    enable=true;
            }
            
    drawTextPixel1010ButtonTitleforcolorbackcolorflg"Arial"14"btn");
        }
        return;
    }

    function 
    main(){
    drawTextPixel1010ButtonTitle+"@URL=EFS:toggle"forcolorbackcolorflg"Arial"14"btn");
    if (
    enable == false) return;  //  don't execute any code
    /*
            do a bunch of stuff
    */
        
    return;


  • #2
    Re: Simple Button

    Hi pj909,

    You have some bad conditionals in your toggle function.

    You also are playing with fire by not defining your variable scope. Allowing the JavaScript engine to assign variable scope is not a good practice and can lead to problems troubleshooting later on.

    Additionally, you are minimizing any potential performance gain by re-drawing the button every tick. Sometimes, creating a drawing object every tick is necessary, but in the case of drawing buttons, it is not.

    Try using the JSLINT tool in the links below (The JavaScript Verifier). While the web app doesn't recognize efs built in objects, it really helps with catching JavaScript problems like you seem to be having.

    Hope this helps,
    Steve


    Originally posted by pj909
    I'm trying to create a toggle button on my chart to allow or dis-allow code processing. But I can't get it to toggle.
    PHP Code:
    debugClear();
    var 
    flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;
    ButtonTitle "Enable"
    backcolor Color.yellow;
    forcolor Color.blue;
    ButtonPressed=null;
    enable false;

    function 
    preMain(){
        
    setPriceStudy(true);
    }

    function 
    toggle(){
        
    Alert.playSound("click.wav");
        if ( 
    ButtonPressed ==  BUTTON_LEFT) {
            if (
    ButtonTitle "Disable"){
                
    ButtonTitle "Enable";
                
    enable=false;
            } else if(
    ButtonTitle "Enable"){  // current state is disabled 
                
    ButtonTitle "Disable";
                
    enable=true;
            }
            
    drawTextPixel1010ButtonTitleforcolorbackcolorflg"Arial"14"btn");
        }
        return;
    }

    function 
    main(){
    drawTextPixel1010ButtonTitle+"@URL=EFS:toggle"forcolorbackcolorflg"Arial"14"btn");
    if (
    enable == false) return;  //  don't execute any code
    /*
            do a bunch of stuff
    */
        
    return;

    Comment


    • #3
      Steve,

      Thanks for the JSLINT link - that's real cool.

      Got the conditional problems fixed, but I'm not sure I follow you on variable scope. I declared my globals - is there something else I should do?

      As for drawing the button every tick - I was am still confused about how to capture the button click. Thought I had to do the button everytime.

      I've tinkered some more since the post and found a sample script that actually calls main() from within the button processor. I tried that and this seems to be working but I would really appreciate some insight into the scope and drawing concerns you had.

      I know it's boring having to answer these amatuer questions - I really appreciate your help. Thanks.
      PHP Code:
      debugClear();
      var 
      flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;
      ButtonTitle "Enable";
      ButtonPressed=null;
      enable false;

      function 
      preMain(){
          
      setPriceStudy(true);
      }
      //== function determines if a button was pressed
      function getButtonPressed(nButtonPressed) {
          if(
      nButtonPressed == BUTTON_LEFT) {
              return(
      1);
          }
          else {
              return(
      0);
          }
      }

      function 
      toggle(nButtonPressed){
          
      Alert.playSound("click.wav");
          
      debugPrintln(nButtonPressed+ButtonTitle); 
          if ( 
      getButtonPressednButtonPressed ) == ) {
              if (
      ButtonTitle == "Disable"){
                 
      ButtonTitle "Enable";
                 
      main();
              } else if(
      ButtonTitle == "Enable"){  // current state is disabled 
                  
      ButtonTitle "Disable";
                  
      main();
              }
          }
          return;
      }

      function 
      main(){

      if (
      ButtonTitle == "Disable"){      //  Currently processing commands - do you wish to disable?
          
      drawTextPixel2020"Disable@URL=EFS:toggle"Color.maroonColor.RGB(255,200,255), flg"Arial"24"btn");
          
      enable=true;
      } else if(
      ButtonTitle == "Enable"){ //  Not currently processing - do you wish to enable?
          
      drawTextPixel2020"Enable@URL=EFS:toggle"Color.darkgreenColor.RGB(200,255,255), flg"Arial"24"btn");
          
      enable=false;
      }

      if (
      enable == false) return;  //  don't execute any code
      /*
              do a bunch of stuff
      */
      debugPrintln("made it passed the exit function");
          return;

      Comment


      • #4
        Steve,

        JSLint wants me to use === (instead of ==) does EFS care?
        it also reports 2 of the functions (getButtonPressed and myButton) were used before being defined. Should I ignore that as well?

        it appears as thought nButtonPressed returns 1,2,3 regardless of the explicit assignment in getButtonPressed. ie The debugPrintln in toggle(nButtonPressed) will print 1,2,3 but never a zero. So why do I need the conditionals or for that matter getButtonPressed. Is nButtonPressed a system value/can I use it directly?

        I put the intial draw button in bInit but not sure how to check after that. It appears as though the rest of the main code is not executing.

        PHP Code:
        debugClear();

        //decalre globals
        var flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;
        var 
        myButtonLabel "Enable";
        var 
        bEnabled false;
        var 
        nButtonPressed=null;
        bInit=false;

        function 
        preMain(){
            
        setPriceStudy(true);
        }   
        // end of premain


        function main(){
            if (
        bInit==false){
                
        myButton();
                
        bInit=true;
            }
            
        toggle(nButtonPressed);
            if (
        bEnabled == false){
                
        debugPrintln("label is "+myButtonLabel+"  no code processing will be done");
                return;  
        //  don't execute any code
            
        }
            
        /*********

            do a bunch of stuff

        *********/

            
        debugPrintln("NO exit - main code was processed");
            return;
        }

        //  button functions group
        function toggle(nButtonPressed){
            
        Alert.playSound("click.wav");
            
        debugPrintln(nButtonPressed+myButtonLabel); 
            if ( 
        getButtonPressednButtonPressed ) == ){
                return;
            }
            if ( 
        getButtonPressednButtonPressed ) == ) {
                
        // toggle/flip the button between enable/disable
                
        if (myButtonLabel == "STOP"){
                   
        myButtonLabel "Enable";
                   
        myButton();
                } else if(
        myButtonLabel == "Enable"){  // current state is disabled 
                    
        myButtonLabel "STOP";
                    
        myButton();
                }
            }
            return;
        }

        //== function determines if a button was pressed
        function getButtonPressed(nButtonPressed) {
            if(
        nButtonPressed == BUTTON_LEFT) {
                return(
        1);
            }
            else {
                return(
        0);
            }
        }

        //  draw the button
        function myButton() {
            if (
        myButtonLabel == "STOP"){      //  Currently processing commands - do you wish to disable?
                
        drawTextPixel2020myButtonLabel+"@URL=EFS:toggle"Color.maroonColor.RGB(255,200,255), flg"Arial"24"btn");
                
        bEnabled=true;
            } else if(
        myButtonLabel == "Enable"){ //  Not currently processing - do you wish to enable?
                
        drawTextPixel2020myButtonLabel+"@URL=EFS:toggle"Color.darkgreenColor.RGB(200,255,255), flg"Arial"24"btn");
                
        bEnabled=false;
            }
            return;

        Comment


        • #5
          Hi pj909,

          Originally posted by pj909
          Steve,

          Thanks for the JSLINT link - that's real cool.
          Your welcome, I use it all the time. I also use the beautifier, each save me a ton of time.



          Got the conditional problems fixed, but I'm not sure I follow you on variable scope. I declared my globals - is there something else I should do?
          I've written quite a bit on scope on the forum, perform a search on "scope" and my user name. Also check the "Handy Links" link to access other links. Don't ignore the Core JavaScript section in the KnowledgeBase either, it is an excellent reference.


          Originally posted by pj909
          Steve,

          JSLint wants me to use === (instead of ==) does EFS care?

          JavaScript is a very flexible language. In the case of comparison operators JavaScript performs automatic type conversion when '==' is used. Type conversion is not performed when "===" is used. Sometime the type conversion is handy, but if not understood, can lead to unexpected results.
          JSLint is an excellent tool to use to write succinct, well defined code, and will by default recommend "===" to minimize the potential for unexpected results. Here is a link that discusses the difference between comparison operators and JavaScript automatic type conversion.




          ... it also reports 2 of the functions (getButtonPressed and myButton) were used before being defined. Should I ignore that as well?
          eSignal EFS is based on core JavaScript 1.5 modified to support the advanced chart environment with custom EFS objects added. See efs JavaScript in the Knowledgebase.
          The JSLint tool does not recognize unique efs functions or objects and will tag them as Global or undefined. In the case of any function or variable, it checks to make sure they are defined before they are used. Typically the eSignal JavaScript compiler identifies global functions and variables first, then compiles the functions. Since you were calling these functions within other functions, they were already identified, and is not an issue.

          JavaScript is flexible, allowing you to declare functions several different ways. When declaring functions with alternate techniques, the order of declaration can cause problems. The JSLint tool is strict and identifies this as an issue. When using the 'function' keyword as you have, you will not have any problems in eSignal.



          it appears as thought nButtonPressed returns 1,2,3 regardless of the explicit assignment in getButtonPressed. ie The debugPrintln in toggle(nButtonPressed) will print 1,2,3 but never a zero. So why do I need the conditionals or for that matter getButtonPressed. Is nButtonPressed a system value/can I use it directly?
          Yes you can, see this nButtonPressed and callback code reference in the Knowledgebase. You can use the native eSignal variables already established in lieu of the numbers, they are equal to the numbers but makes the code more readable.



          I put the intial draw button in bInit but not sure how to check after that. It appears as though the rest of the main code is not executing.
          I see some issues in your code, check my FileShare (link below) for some examples. I'll help you work through the concepts, (the examples will help). Once you understand, we can compare your working efs with my re-write and discuss differences.

          Hope this helps.

          Steve

          Comment


          • #6
            OK Steve, been reading the various links you gave (thank you). But at this point I'm hopelessly lost. For example: is getButtonPressed() a system function? where is the documentation on it? I presume nButtonPressed is simply global but it's not shown as such. I wish eSignal would create a more thorough document on this so we amatuers didn't have to rely on the genersosity of good folks like you. The KB has hardly any info - your code examples show much more. I looked them over and tried to replicate the logic but now I feel like Edison: I've found a 1000 ways it doesn't work. (well probably less than 100 anyway ). I'm never getting a chance to toggle my STOP button.

            PHP Code:
            debugClear();
            //decalre globals
            var flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;
            var 
            myButtonLabel "Enable";
            var 
            bEnabled false;
            var 
            nButtonPressed null;
            bInit=false;

            function 
            preMain(){
                
            setPriceStudy(true);
            }   
            // end of premain

            function main(){
                if (
            bInit==false){
            //       drawTextPixel( 20, 20, myButtonLabel+"@URL=EFS:myButton", Color.maroon, Color.RGB(255,200,255), flg, "Arial", 24, "btn");
                    
            getButtons();
                    
            bInit=true;
                }

                if (
            bEnabled == false){
                    
            debugPrintln("no code processing will be done until bEnabled is toggled to true");
                    return;  
            //  don't execute any code
                
            }    
            /*********

                do a bunch of stuff

            *********/
                
            debugPrintln("bEnabled was true - main code was processed");
                return;
            }

            //  draw the button
            function myButton(nButtonPressed) {  
                
            getButtonPressed(nButtonPressed)
                if ( 
            getButtonPressednButtonPressed ) == )  {       // if left mouse button was clicked - toggle the STOP/Enable button          
                    
            if (bEnabled == false){
                        
            bEnabled true;
                        
            myButtonLabel "STOP";
                    } else if(
            bEnabled == true){
                        
            bEnabled false;
                        
            myButtonLabel "Enable";
                    }
                }                                                       
            // if no click (nButtonPressed=0) return w/o changes
                
            return;
            }
            function 
            getButtons(){//required
            //    drawTextPixel( xx, yy, nButtonTitle +" @URL=EFS:catchme", forcolor, backcolor, flg,"Comic Sans MS", 20, -5);//required
                 
            drawTextPixel2020myButtonLabel+"@URL=EFS:myButton"Color.maroonColor.RGB(255,200,255), flg"Arial"24"btn");
            }

            //== function determines if a button was pressed
            function getButtonPressed(nButtonPressed) {
              if(
            nButtonPressed == BUTTON_LEFT) {return(1);}
              if(
            nButtonPressed == BUTTON_RIGHT) {return(2);}
              if(
            nButtonPressed == BUTTON_LEFTDBLCLK) {return(3);}
                else {return(
            0);}

            Comment


            • #7
              Here is how I would do it (very simple solution).

              PHP Code:

              var vLogicalToggle false;
              var 
              flg Text.RELATIVETOLEFT|Text.RELATIVETOBOTTOMText.FRAME Text.ONTOP ;


              function 
              main() {

                if (
              getCurrentBarIndex() == 0) {
                  
              getButtons();
                }



                 if (
              vLogicalToggle) {
                   
              //  logic switch is ON, run this section of code

                 
              } else {
                   
              //  logic switch is OFF, do nothing

                 
              }

              }

              function 
              getButtons(){
                if (
              vLogicalToggle) {
                   
              drawTextPixel2020"Toggle Btn"+"@URL=EFS:myButton"Color.maroonColor.RGB(200,255,200), flg"Arial"24"btn");
                } else {
                   
              drawTextPixel2020"Toggle Btn"+"@URL=EFS:myButton"Color.maroonColor.RGB(255,200,200), flg"Arial"24"btn");
                }
              }

              function 
              myButton() {
                if (!
              vLogicalToggle) {
                  
              vLogicalToggle true;
                } else {
                  
              vLogicalToggle false;
                }
                
              getButtons();

              This is how I try to handle logical (switch) type of buttons in my projects. This code should show a GREEN button when ON and a RED button when OFF.

              Hope this helps?
              Brad Matheny
              eSignal Solution Provider since 2000

              Comment


              • #8
                Thanks Brad. That helps a lot.

                I've been a bit confused about the callback in getButtons() calling myButton which turns around and calls getButtons(). I thought I shouldn't make a recursive loop. Is that recursive loop the mechanism to make sure we can capture any click - any time? In other words, forgetting the logic toggle: draw pixel w/button activates the capture of mouse clicks ON THAT BUTTON. The callback gives me a means to process the button events but it must "call back" to the draw function.

                Also, you are calling getButtons() on every new bar rather than just once in bInit. If the recursive loop captures all clicks and redraws as needed, wouldn't drawing every bar add extra overhead?

                Comment


                • #9
                  Yes. You are correct. The way I'm calling the drawing of the buttons adds a small bit of overhead to the efs script. The solution to this is to encompass the "getCurrentBarIndex" function in an INIT condition or a NEW BAR condition. This will cause the buttons to be redrawn as a new bar forms or only once at the end of the init function.

                  Additionally, every time you click on a button, you'll want to call to redraw the buttons after you complete the button action. This way the color changing features of the buttons are instant. If you don't do this, then the color changes will only be visible on the next tick of the chart.

                  It's all about how you want to develop your EFS to maintain speed and operation. For Autotrading robots, I use a timer feature that is combined with the conditions of the trading system.

                  If it is not in a trade, then I normally redraw the buttons every 5~10 seconds. If it is in a trade and is reporting data in realtime using buttons, then I normally use a 2~3 second timer.

                  Again, glad I could help. Let me know if you need more assistance?
                  Brad Matheny
                  eSignal Solution Provider since 2000

                  Comment


                  • #10
                    Brad, got my test routine working smoothly using your template. I should be able to incorporte into my trading routine without any trouble now. THANK YOU!

                    Why, are you using timer loops to redraw stuff? Do those loops also delay the button click - event handling? In my case I want that emergency stop button availabe at any instant. Not sure why you would want to use a timer loop.

                    PJ
                    Attached Files

                    Comment


                    • #11
                      No, the timers do not delay the buttons or button actions. They are simply a mechanism to improve the processing speed of the EFS in eSignal.

                      When developing an automated trading system, I often use drawTextPixel to report REALTIME data from the trading robot. Drawing this realtime data every tick can slow down the robot. Thus, drawing it every n seconds is a better way of reporting the data vs. redrawing every tick.

                      Also, with a robot, you want the user to be able to control the robot and get nearly instant results from the broker connection. Thus, developing a "controlling system" for drawing features and broker features is important. I've developed a means of knowing when the robot has executed a trade (or trade action) and then have my robot update the on-screen text reporting.

                      Remember, I've been doing this type of stuff for over 10 years. So I've run into many of the common issues other efs developers hit when they develop projects.

                      Think of it as "I might be a bit further down the rabbit hole than other developers".

                      BTW, they're not loops. There is another way to develop a timer function in efs without using loops.
                      Last edited by Doji3333; 09-01-2010, 08:50 AM.
                      Brad Matheny
                      eSignal Solution Provider since 2000

                      Comment


                      • #12
                        OK Brad - you've tweaked my curiosity. Since this is my first robot I was wondering if I could look down your rabbit hole. I didn't find any recent scripts on your file share that show the timing loop and/or IB integration. Have you got any simple examples you would be willing to share?
                        "Alice"

                        Comment


                        • #13
                          If you search this forum for "timer", you'll see some posts I made about a year ago on this topic. They are not hard to create, you just need to use the REALTIME date/time features to initiate a timer.

                          Secondly, I'm restricted from posting links to my site or anything that could be considered advertising of my services on this forum. Thus, in order to maintain a proper professionaly relationship with esignal, I will PM you the details you requested.

                          If you need any additional support of esignal or efs scripting, just let me know?
                          Brad Matheny
                          eSignal Solution Provider since 2000

                          Comment

                          Working...
                          X