Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Tip: How to round a calculated price by the tick size of an instrument?

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

    Tip: How to round a calculated price by the tick size of an instrument?

    When you calculate the price based on a formula within your custom indicator or strategy, you often need to round it by the tick size of the instrument in question. For example, your indicator initially gives 1408.673 as the stop price for your E-mini S&P 500 trading. However, the tick size of the instrument is 0.25. You need to round 1408.673 to 1408.75 before using it to enter an order.

    Here is the NinjaScript expression that just does that:

    price - price % TickSize + ((price % TickSize < TickSize / 2) ? 0.0 : TickSize);

    If you are already familiar with the % and ? operators, the expression should make sense to you immediately. For those who are not, let me explain it to you one step a time.

    First, TickSize is a property of any indicator or strategy in NinjaScript. It represents the minimum fluctuation in price of an instrument. For E-mini S&P 500, its value is 0.25.

    Second, "%" is the modulus operator in C#. It computes the remainder after dividing its first operand by its second. To illustrate, 9 % 3 yields 0, 9 % 2 yields 1, and 9 % 0.7 yields 0.6. Therefore, price % TickSize or 1408.673 % 0.25 yields 0.173. Now you can see that the first part of the expression, price - price % TickSize, yields 1408.50, a valid price that is closet to but smaller than the initial one.

    However, this is not the final result yet. Did you notice the remainder, 0.173 is more than half of the tick size, 0.25 / 2 or 0.125? So the third step is to add a tick size to the result when the situation occurs.

    The second part of the expression, ((price % TickSize < TickSize / 2) ? 0.0 : TickSize), just does that. It uses the conditional operator in C#, "?". Here is a general expression using the operator, condition ? value 1 : value 2. The expression equals to value 1 when the condition is true; it equals to value 2 when the condition is false. To illustrate, the value of (100 > 50) ? 1 : 2 is 1 because 100 is larger than 50. On the other hand, the value of (10 > 50) ? 1 : 2 is 2 because 10 is smaller than 50.

    The condition in our expression is price % TickSize < TickSize / 2, that is, the remainder is smaller than half of the tick size. When this is true, 0.0 as value 1 is added to the result. When it is false, the tick size as value 2 is added to the result. The final result is a “legitimate” price for the instrument rounded from the initial one.

    To recap, simply replace the price variable in the expression above with any value and you can round it by the tick size of any instrument.

    #2
    Originally posted by KamaCoder Eric View Post
    When you calculate the price based on a formula within your custom indicator or strategy, you often need to round it by the tick size of the instrument in question. For example, your indicator initially gives 1408.673 as the stop price for your E-mini S&P 500 trading. However, the tick size of the instrument is 0.25. You need to round 1408.673 to 1408.75 before using it to enter an order.

    Here is the NinjaScript expression that just does that:

    price - price % TickSize + ((price % TickSize < TickSize / 2) ? 0.0 : TickSize);

    If you are already familiar with the % and ? operators, the expression should make sense to you immediately. For those who are not, let me explain it to you one step a time.

    First, TickSize is a property of any indicator or strategy in NinjaScript. It represents the minimum fluctuation in price of an instrument. For E-mini S&P 500, its value is 0.25.

    Second, "%" is the modulus operator in C#. It computes the remainder after dividing its first operand by its second. To illustrate, 9 % 3 yields 0, 9 % 2 yields 1, and 9 % 0.7 yields 0.6. Therefore, price % TickSize or 1408.673 % 0.25 yields 0.173. Now you can see that the first part of the expression, price - price % TickSize, yields 1408.50, a valid price that is closet to but smaller than the initial one.

    However, this is not the final result yet. Did you notice the remainder, 0.173 is more than half of the tick size, 0.25 / 2 or 0.125? So the third step is to add a tick size to the result when the situation occurs.

    The second part of the expression, ((price % TickSize < TickSize / 2) ? 0.0 : TickSize), just does that. It uses the conditional operator in C#, "?". Here is a general expression using the operator, condition ? value 1 : value 2. The expression equals to value 1 when the condition is true; it equals to value 2 when the condition is false. To illustrate, the value of (100 > 50) ? 1 : 2 is 1 because 100 is larger than 50. On the other hand, the value of (10 > 50) ? 1 : 2 is 2 because 10 is smaller than 50.

    The condition in our expression is price % TickSize < TickSize / 2, that is, the remainder is smaller than half of the tick size. When this is true, 0.0 as value 1 is added to the result. When it is false, the tick size as value 2 is added to the result. The final result is a “legitimate” price for the instrument rounded from the initial one.

    To recap, simply replace the price variable in the expression above with any value and you can round it by the tick size of any instrument.

    Nice to know thanks, I always use Bars.Instrument.MasterInstrument.Round2TickSize( price ), but never think the way you explain it.

    Comment


      #3
      I was not aware that Bars.Instrument.MasterInstrument has a method called Round2TickSize. Neither the IntelliSense in the NinnjaScript Editor nor the Search in the Help Guide gives a clue that such a method exists. But it does! Thank you, PrTester!

      My test did show one unexpected behavior of Round2TickSize. When the price is at half the tick size, the method rounds it down instead of rounding it up.

      Comment


        #4
        >> When the price is at half the tick size, the method rounds it down instead of rounding it up.
        Unfortunately your logic below exhibits the same problem: please try 9.995 and 0.01 as tick size. Returns 9.99 here.

        Please let me know as you found a way to reliably round up on half a tick size. Thanks

        Comment


          #5
          My earlier test used 1410.125 as the price and 0.25 as the tick size. My expression rounded it correctly, but not Round2TickSize.

          Now with 9.995 as the price and 0.01 as the tick size, both failed to round it up.

          I did find a solution - cast both price and tick size to decimal first.

          Here is the updated expression...actually, it is now a function:

          private double Round(double price)
          {
          decimal p = (decimal)price;
          decimal t = (decimal)TickSize;

          return (double)(p - p % t + ((p % t < t / 2) ? 0M : t));
          }
          Last edited by KamaCoder Eric; 05-12-2008, 01:33 AM.

          Comment


            #6
            Excellent! I'll amend Round2TickSize accordingly. Thanks for pointing that out.

            Comment


              #7
              I am wondering why neither intellisense nor the help guide reveals the existence of Round2TickSize. Did I miss something? Thanks!

              Comment


                #8
                Nope. It just was not part of documented NinjaScript. We'll reconsider that.

                Comment


                  #9
                  Does this code work as expected in NT7?

                  If yes, it would be the solution to my problem in the other thread.

                  Comment


                    #10
                    I believe so symphys, saw no issues on a quick check here - will look into your other thread and issue shortly.
                    BertrandNinjaTrader Customer Service

                    Comment


                      #11
                      While rounding to the nearest tick has it's uses you really need to be aware of why you are rounding. Think of a stop order on a stock with a tick of .01. I need all of my buy prices rounded up while I need my Sell stops rounded down.

                      If my math creates a buy point at 87.0175, I need this rounded up to 87.02 as my prices isn't touched until then. Even a price of 87.0100001 needs to be rounded up to 87.02.

                      if I create a sell point at 87.0175, I need this rounded down to 87.01 as my price isn't touched until then. Even 87.01999999 needs to be rounded down to 87.01.

                      Might not seem like much, but if you want precision you need to allow this to happen.

                      W2

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by judysamnt7, 03-13-2023, 09:11 AM
                      4 responses
                      59 views
                      0 likes
                      Last Post DynamicTest  
                      Started by ScottWalsh, Today, 06:52 PM
                      4 responses
                      36 views
                      0 likes
                      Last Post ScottWalsh  
                      Started by olisav57, Today, 07:39 PM
                      0 responses
                      7 views
                      0 likes
                      Last Post olisav57  
                      Started by trilliantrader, Today, 03:01 PM
                      2 responses
                      21 views
                      0 likes
                      Last Post helpwanted  
                      Started by cre8able, Today, 07:24 PM
                      0 responses
                      10 views
                      0 likes
                      Last Post cre8able  
                      Working...
                      X