Announcement

Collapse
No announcement yet.

How to speed up efs performance time

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

  • How to speed up efs performance time

    Hello:

    I've created an efs formula that compares highs and lows on recent price bars in order to find ideal entry points. The efs works great but it is slow compared to other efs formulas I use (according to the performance monitor).

    Here's an excerpt of the script. There's a counter to keep track of valid comparisons, and then look for a total count. I tried combining some comparisons together into one if statement using &&, but this slowed the script down considerably. I was wondering whether retrieving the data needed into an array and then comparing the values would be faster than retrieving and comparing the bar values one by one. Are there any other ways to speed up efs performance?

    // 3 lower highs on last 3 candles
    if (high(-1) > high(0)) {
    iScore = iScore+1;
    }
    if (high(-2) > high(-1)) {
    iScore = iScore+1;
    }

    if (high(-3) > high(-2)) {
    iScore = iScore+1;
    }

    // 2 lower lows on last 2 candles
    if (low(-1) > low(0)) {
    iScore = iScore+1;
    }
    if (low(-2) > low(-1)) {
    iScore = iScore+1;
    }

    price keeps above 20 ma

    if (low(0) >= sma(20,0)) {
    iScore = iScore+1;
    }

    // valid entry point if all tests are true
    if (iScore == 6) {
    sSymbol = getSymbol();
    Alert.addToList(sSymbol, "valid entry point", Color.blue, Color.grey);
    }

    **************

    Thanks in advance.
    jt_trader
    Last edited by jt_trader; 09-08-2010, 01:55 PM.

  • #2
    If all 6 conditions must be met for you to have a valid signal then put them all in one IF statement separated by the "&&" operator. That is guaranteed to be faster than your way because your way has 6 conditional tests while one IF statement will stop the comparisons on the first false condition (this is called short-circuit logic). [btw, you would want the 20 sma test to be done first; otherwise, there's no need to compare any other highs vs. lows]

    Call setComputeOnClose() in your preMain() function. That will fix your performance issue. There's no need for the code you've posted to be checked except on the start of a new price bar.

    If you have other code in the script which needs to be run on every price tick, then instead of putting setComputeOnClose() in the preMain(), surround the code which only needs to be run on each new bar with this:

    if (getBarState() == BARSTATE_NEWBAR)
    {
    ...
    }

    Comment


    • #3
      SteveH's reply is correct. Although, with such a small piece of code, it should not be taking much time to complete even in its current form.
      Brad Matheny
      eSignal Solution Provider since 2000

      Comment


      • #4
        Thanks for the replies, I really appreciate it.

        I agree with you Doji3333 that the code that I've posted shouldn't take that long to process. FYI this code snippet is a test for the candlestick pattern known as the Rising Three Methods, which is a pattern known to many. This test is actually a small part of my entire EFS, which I can't post in its entirety as it is the proprietary strategy of a senior trader who is mentoring me. The entire EFS has over 200 lines of code. I guess I should have mentioned this with my original post. Sorry about that.

        It's the first time that my mentor's strategy is being automated in eSignal, which is why I'm experiencing some bumps along the way.

        In the EFS there are many if statements with comparisons to highs, lows and sma's. I was wondering in general whether gathering all the high, low and sma values at once and storing them in an array for comparison later was more efficient than gathering these values one by one as they need to be compared, as I'm currently doing. From your replies it looks like arrays won't speed things up. At any rate, I don't have much experience using arrays.

        Thank you for your suggestions SteveH. I'm used to coding in VB6 and didn't know about short circuit logic. Your idea of first evaluating a condition that isn't true very often is a good one. The actual logic needed to reproduce the full strategy is rather complex, with some 20 conditions needing to be evaluated. However, you need to evaluate different sets of conditions depending on the results of the first conditions tested. (I hope I'm making sense). The end result is that trying to put everything into one if statement is a considerable challenge.

        FYI, I've done some experimenting with the EFS and using the EFS Performance Monitor, I've got the average run time for the EFS from just over 1 ms to .65 ms. This is a great help, since the idea is to run the same EFS formula on several charts on the same page in eSignal.

        By trial and error, here are two things that I've found to speed up the execution of the EFS:

        1. Avoid compound if statements.

        By trial and error, I found that this:

        if (condition A) {
        if (condition B) {
        statement A;
        statement B;
        }
        }

        will run faster than this:

        if (condition A && condition B) {
        statement A;
        statement B;
        }

        especially when condition A is something that is not true very often.

        From your post replies Doji3333 and SteveH, I realize that this may run counter to your experience. I can't explain why, but this is what I found in my own testing.

        2. Keep lines of code in main function to a minimum, especially when using if statements; call other functions instead.

        By trial and error, I found that this:

        function main {
        if (A>B) {
        doChoiceA();
        }
        else {
        doChoiceB();
        }
        }

        function doChoiceA() {
        statement A;
        statement B;
        statement C;
        }

        function doChoiceB() {
        statement D;
        statement E;
        statement F;
        statement G;
        }

        will run faster than this:

        function main {
        if (A>B) {
        statement A;
        statement B;
        statement C;
        }
        else {
        statement D;
        statement E;
        statement F;
        statement G;
        }
        }

        Again, I can't explain why the above is true, but this is what I found in my own testing.

        You got me thinking SteveH. I can't evaluate the price bar on close, as I'm daytrading on 5 minute price bars, and evaluating the bar on close doesn't give enough time to react. There are some parts of the strategy that can't be automated and need to be done manually once all the test conditions are true. And I need to evaluate the EFS after a price bar has opened, as the price movement in the bar could cause the test conditions to become invalid before the bar closes.

        So, here's a code snippet I found that does all the tests on a price bar when it first starts forming, and every 10 ticks until it closes. This does speed up the EFS, as the tests aren't done on every tick:

        if (getBarState()==BARSTATE_NEWBAR) {
        doTests();
        count=0;
        }
        count++;
        if (count%10==0) doTests();


        Using all the above ideas, the main function in the EFS is down to 35 lines of code, and the execution time of the EFS has been reduced by one third.

        Thank you again for all your suggestions.
        Last edited by jt_trader; 09-14-2010, 02:15 AM.

        Comment


        • #5
          I'd like to add a new discovery that can help speed up EFS formulas. It doesn't always work, but it seems to work sometimes. This is added to the three discoveries already noted in this thread:

          4. Avoid compound math statements.

          Example: I wanted a formula that would tell me the average true range of 2 minute price bars, expressed in a number of cents, so that .25523525 is expressed as 25.5.

          By trial and error, I found that this:

          var vATR;
          var vATRmil;
          var vATRround;
          var vATRout;

          function main() {
          vATR = atr(5,inv("2"),-1);
          vATRmil = 1000*vATR;
          vATRround = Math.round(vATRmil)
          vATRout = vATRround/10;

          return (vATRout);
          }

          will run faster than this:

          var vATRout;

          function main() {
          vATRout = Math.round(1000*(atr(5,inv("2"),-1)))/10;
          return (vATRout);
          }

          =========

          Cheers.
          Last edited by jt_trader; 09-24-2010, 02:35 PM.

          Comment


          • #6
            Hi jt_trader,

            Very useful tips.

            Wayne

            Comment


            • #7
              Originally posted by jt_trader
              I'd like to add a new discovery that can help speed up EFS formulas. It doesn't always work, but it seems to work sometimes. This is added to the three discoveries already noted in this thread:

              4. Avoid compound math statements.

              Example: I wanted a formula that would tell me the average true range of 2 minute price bars, expressed in a number of cents, so that .25523525 is expressed as 25.5.

              By trial and error, I found that this:

              var vATR;
              var vATRmil;
              var vATRround;
              var vATRout;

              function main() {
              vATR = atr(5,inv("2"),-1);
              vATRmil = 1000*vATR;
              vATRround = Math.round(vATRmil)
              vATRout = vATRround/10;

              return (vATRout);
              }

              will run faster than this:

              var vATRout;

              function main() {
              vATRout = Math.round(1000*(atr(5,inv("2"),-1)))/10;
              return (vATRout);
              }

              =========

              Cheers.
              Do you have the numbers of improvement on this?

              AS far as I can tell, the difference should not be significant.

              Just my thought.

              Comment


              • #8
                Originally posted by SteveH
                If all 6 conditions must be met for you to have a valid signal then put them all in one IF statement separated by the "&&" operator. That is guaranteed to be faster than your way because your way has 6 conditional tests while one IF statement will stop the comparisons on the first false condition (this is called short-circuit logic)....
                }
                Well, embedded if statements do the same thing. If the first one is false, none of the others will get evaluated.

                You have to make sure that you put the ones that will be false most often up front so they kick out control more often -- saving further execution of additional statements inside the if brackets.

                Right?

                Comment

                Working...
                X