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

If statement and comparing double equality

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

    If statement and comparing double equality

    I have an "if" statement that looks for doubles being equal:

    if(Low[1] == LowPivotOne)

    where: LowPivotOne is a double

    LowPivotOne is set via: LowPivotOne = Low[1];

    Essentially this is checking to see if the current Low[1] is equal to the previous low pivot.

    Problem is, this method is random. Sometimes it works and other times it doesn't. I've searched on this problem and learned that comparing doubles for equality is problematic. This is because doubles are not stored as precise numbers and will have small offsets.

    I've tried Convert.To.Decimal but that started getting out of hand. I had to continually convert more and more variables and it just didn't seem the most elegant solution.

    Is there a fairly simple way to compare two doubles for equality in an If statement?

    regards,
    taddypole...

    #2
    More research and found the :

    double1.Equals(double2));

    trying that....see if that works....

    Comment


      #3
      if((High[1] - (1 * TickSize)).Equals(HighPivotSeven))
      {
      DrawDiamond("MyDiamondHighPvtSevenOneTickStopOut" + CurrentBar, true, 1, High[1] + 1 * TickSize, Color.Gold);
      }


      Print("");
      Print(" All Pivots");
      Print(" Time[1] = " + Time[1]);
      Print(" CurrentBar - 1 = " + (CurrentBar - 1) + " *** aaaTrgKeltIndyTwo");
      Print(" High[1] = " + High[1].ToString("00.00000000"));
      Print(" High[1] - (1 * TickSize) = " + (High[1] - (1 * TickSize)).ToString("00.00000000"));
      Print(" HighPivotOne = " + HighPivotOne.ToString("00.000000000"));
      Print(" HighPivotTwo = " + HighPivotTwo.ToString("00.000000000"));
      Print(" HighPivotThree = " + HighPivotThree.ToString("00.000000000"));
      Print(" HighPivotFour = " + HighPivotFour.ToString("00.000000000"));
      Print(" HighPivotFIve = " + HighPivotFive.ToString("00.000000000"));
      Print(" HighPivotSix = " + HighPivotSix.ToString("00.000000000"));
      Print(" HighPivotSeven = " + HighPivotSeven.ToString("00.000000000"));
      Print(" TickSize = " + TickSize.ToString("00.000000000"));
      Print("");

      I'm using the double1.Equals(double2) method in the code above and it still doesn't work. In the above code I print out the values and it says it should have fired but it doesn't draw my Diamond.
      Attached Files

      Comment


        #4
        if(High[1].Equals(HighPivotSeven))
        {
        DrawDot("MyDotHighTouchSeven" + CurrentBar, true, 1, High[1] + 1 * TickSize, Color.Magenta);
        }

        What's weird is in code above that doesn't look for a one tick offset, it seems to work fine. It's just when I use the one tick offset that It becomes random, working some times and not others.

        Regards,
        taddypole...

        Comment


          #5
          Attached is a output window showing some that worked and one that didn't.

          Any ideas anyone?
          Attached Files

          Comment


            #6
            I had the same issue ages ago and was trying to find the code that I ended up solving this with. No doubt there is a more elegant solution however, I am pretty sure I ended up rounding both doubles before comparing them and this worked.

            Try making a simple bool func that rounds the 2 vals before comparing.

            eg.

            Code:
            		bool isSame(double val1, double val2)
            		{
            			int decPlaces = 9; //I have a func that auto finds my dec places 
            			
            			val1 = Math.Round(val1 , decPlaces, MidpointRounding.ToEven);
            			val2 = Math.Round(val2 , decPlaces, MidpointRounding.ToEven);
            			
            			if (val1 == val2) return(true);
            			return(false);
            		}

            Comment


              #7
              Hello Taddypole, and thank you for your question.

              The traditional software engineering solution to this problem is to assign a fault tolerance range. I can give an example.

              Code:
              double pi = 3.1415926;
              double reallyPi = 4 * Math.Atan(1.0);
              if (Math.Abs(pi - reallyPi) < 0.000001)
              {
                  Print("Pi is " + pi);
              }
              A good rule of thumb is to use 1 less significant figure than your least precise measurement. In the example above, there were 7 numbers after the decimal point, and so I checked for a difference 6 numbers after the decimal point.

              Please let us know if there are any other ways we can help.
              Jessica P.NinjaTrader Customer Service

              Comment


                #8
                oneTickLowerHigh = High[1] - 1 * TickSize;

                // One Tick Stop Out
                if(Math.Abs(oneTickLowerHigh - HighPivotTwo) < tolerance)
                {
                DrawDiamond("MyDiamondHighPvtTwoOneTickStopOut" + CurrentBar, true, 1, High[1] + offSetTrendDn * TickSize, Color.Gold);

                Print("");
                Print(" DiamondHighPvtTwoOneTickStopOut");
                Print(" Time[1] = " + Time[1] + " CurrentBar - 1 = " + (CurrentBar - 1) + " *** aaaTrgKeltIndyTwo");
                Print(" High[1] = " + High[1].ToString("00.0000000000") + " HighPivotTwo = " + HighPivotTwo.ToString("00.0000000000"));
                Print(" oneTickLowerHigh = " + oneTickLowerHigh.ToString("00.0000000000"));
                Print(" Math.Abs(oneTickLowerHigh-HighPivotTwo) = " + Math.Abs(oneTickLowerHigh - HighPivotTwo).ToString("00.0000000000") + " < " + " tolerance = " + tolerance);
                Print("");
                }

                Jessica,

                I tried your Math.Abs method but now I get too many passing through the "If" statement.
                Why is that?

                regards,
                taddypole...
                Attached Files

                Comment


                  #9
                  Originally posted by marty087 View Post
                  I had the same issue ages ago and was trying to find the code that I ended up solving this with. No doubt there is a more elegant solution however, I am pretty sure I ended up rounding both doubles before comparing them and this worked.

                  Try making a simple bool func that rounds the 2 vals before comparing.

                  eg.

                  Code:
                  		bool isSame(double val1, double val2)
                  		{
                  			int decPlaces = 9; //I have a func that auto finds my dec places 
                  			
                  			val1 = Math.Round(val1 , decPlaces, MidpointRounding.ToEven);
                  			val2 = Math.Round(val2 , decPlaces, MidpointRounding.ToEven);
                  			
                  			if (val1 == val2) return(true);
                  			return(false);
                  		}
                  Thank you marty087

                  Not being a programmer by profession can you tell me where that code goes?
                  I understand how to use it but by just inserting the code into my code, I get programming errors.
                  sorry... no formal coding education...

                  regards,
                  taddypole...

                  Comment


                    #10
                    I am having some trouble reproducing what you are seeing on my end. Would it be possible for you to replace

                    Math.Abs(oneTickLowerHigh - HighPivotTwo).ToString("00.0000000000")

                    by

                    String.Format("{0:C}", Math.Abs(oneTickLowerHigh - HighPivotTwo))

                    in your code, and send me those results?
                    Jessica P.NinjaTrader Customer Service

                    Comment


                      #11
                      Jessica,

                      Here's how I entered your suggestions in the Print statement:

                      Print("String.Format('{0:C}}', Math.Abs(oneTickLowerHigh-HighPivotTwo) = " + String.Format("{0:C}}",Math.Abs(oneTickLowerHigh - HighPivotTwo)) + " < " + " tolerance = " + tolerance);

                      and here are the results:

                      Error on calling 'OnBarUpdate' method for indicator 'aaaTriggerandKeltnerIndTwoA' on bar 416: Input string was not in a correct format.

                      What does this mean?

                      regards,
                      taddypole...

                      Comment


                        #12
                        It looks like your format string has one more } than mine does.

                        My format string : "{0:C}"

                        The format string you are using : "{0:C}}"
                        Jessica P.NinjaTrader Customer Service

                        Comment


                          #13
                          Thanks Jessica,

                          Just had cataract surgery on one eye... and still adjusting.

                          I used the "C" for currency and also tried the "e" for scientific.

                          The results are in the attachment.

                          regards,
                          Attached Files

                          Comment


                            #14
                            Thank you Taddypole. This appears to be a bug. Would it be possible to provide us with a stripped down version of your complete source so we can investigate this further? With this type of bug, the code you wrote in the immediate area is likely not responsible for the behavior you are observing.
                            Jessica P.NinjaTrader Customer Service

                            Comment


                              #15
                              Jessica,

                              Attached are the stripped down indicator and a picture of the chart showing an example of the multiple cases where many comparisons got through. These are the obvious ones. There are many others when you look closely.

                              Regards,
                              taddypole...
                              Attached Files

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Jon17, Today, 04:33 PM
                              0 responses
                              1 view
                              0 likes
                              Last Post Jon17
                              by Jon17
                               
                              Started by Javierw.ok, Today, 04:12 PM
                              0 responses
                              4 views
                              0 likes
                              Last Post Javierw.ok  
                              Started by timmbbo, Today, 08:59 AM
                              2 responses
                              10 views
                              0 likes
                              Last Post bltdavid  
                              Started by alifarahani, Today, 09:40 AM
                              6 responses
                              40 views
                              0 likes
                              Last Post alifarahani  
                              Started by Waxavi, Today, 02:10 AM
                              1 response
                              19 views
                              0 likes
                              Last Post NinjaTrader_LuisH  
                              Working...
                              X