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

Trying to remove line when new bar is in the way

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

    Trying to remove line when new bar is in the way

    Hey, I hope someone is able to help me with what I'm trying to do. Let me start by saying I'm not a programmer by any means and everything I've done is with minimal programming knowledge and mostly trial and error.

    I found the following indicator and have been using it as the base of what I'm trying to create.
    https://ninjatraderecosystem.com/use...ad/swingrays2/
    I've taken this script and adjusted it to get to where it is now.

    So, basically what I'm trying to create here is a "resistance" indicator that will draw a horizontal line across the chart at a specified area and stop the line ONLY when the body of a bar gets in the way of it. However the problem I'm having now is the line is being removed even when the body of the bar is not in the way.

    I think I know where the problem is within my code, but the solution that I thought of ends up almost breaking everything.

    Currently I have

    while ( swingHighRays.Count != 0 && currentBarStatus == bullish && Close[0] > tmpRay.StartAnchor.Price)
    {

    RemoveDrawObject(tmpRay.Tag);

    }

    Which will remove the resistance line as soon as any bar closes above the price of when the line was drawn. I thought that if I edited it to the following, it would fix the problem.

    while ( swingHighRays.Count != 0 && currentBarStatus == bullish && Close[0] > tmpRay.StartAnchor.Price && Open[0] < tmpRay.StartAnchor.Price)
    {

    RemoveDrawObject(tmpRay.Tag);

    }

    Is there something I'm not understanding about the parameters that I'm putting in and that's why everything just breaks?
    I think I'm missing some logic to my code to fix every situation but I thought the mentioned above code would at least fix this bit.
    I don't even know where the problem lies so I'm not sure where / how to troubleshoot this. It kind of looks like it's working sometimes but for the most part, the lines are not being removed.

    I have attached a couple screenshots for clarification and my current code.
    The orange lines are supposed to be the removed lines and the blue lines are supposed to be ongoing lines.

    Any suggestions to fix or even a completely different solution to the whole thing would be greatly appreciated

    Thanks
    Attached Files
    Last edited by timoting; 09-13-2021, 05:28 PM.

    #2
    Hello timoting,

    Thanks for the post.

    So that I can further assist, are you trying to detect when the price crosses specifically? The solution you came up with could potentially work for making a range of prices which would only remove the object in that small window. The second price would need to be offset some rather than being the same price.

    If you are trying to detect the cross over you could use the CrossAbove or CrossBelow conditions here.


    Code:
    if(CrossAbove(Close, tmpRay.StartAnchor.Price, 1) && other parts)
    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Hello Jesse,

      I am trying to remove the line whenever a bar closes and it's in the way. The first photo I've uploaded illustrates what I want.

      I've never used the CrossAbove and CrossBelow conditions so I'll need to take a look in the help guide. Would I be able to use those conditions for something like :
      if current bar crosses above or crosses below the line then remove line

      Thanks for your time
      Last edited by timoting; 09-14-2021, 11:01 AM.

      Comment


        #4
        Hello timoting,
        Thanks for the reply.

        Yes the CrossAbove/Below methods accomplish that. The syntax I provided in the last post is an example of using the CrossAbove.







        I look forward to being of further assistance.
        JesseNinjaTrader Customer Service

        Comment


          #5
          Hello Jesse,
          Thanks for helping again.

          I've tried what you suggested but I must be doing something wrong because it's not working. I tried to keep the structure of the original code since I was afraid of unintentionally breaking something. The following is the main chunk of code that's in play.


          Code:
          ///Resistance
          if(currentBarStatus == bearish && previousBarStatus == bullish && Open[0] == Close[1])
          {
          Ray newRay = Draw.Ray(this, "highRay" + CurrentBar, false, 1, Open[0], 0, Open[0], SwingHighColor, DashStyleHelper.Dash, LineWidth);
          swingHighRays.Push(newRay);
          }
          
          
          
          // Check the break of some swing
          // High swings first...
          Ray tmpRay = null;
          
          if ( swingHighRays.Count != 0 )
          {
          tmpRay = (Ray)swingHighRays.Peek();
          }
          
          while ( swingHighRays.Count != 0)
          {
          Print("swing high count " + swingHighRays.Count);
          Print("Start anchor price " + tmpRay.StartAnchor.Price);
          Print("Close value " + Close);
          if(CrossAbove(Close, tmpRay.StartAnchor.Price, 1))
          {
          Draw.Dot(this, "dot" + CurrentBar, false, 0, Close[0], Brushes.Red);
          Print("crossing over");
          RemoveDrawObject(tmpRay.Tag);
          }
          
          if ( KeepBrokenLines )
          { // Draw a line for the broken swing
          int uiBarsAgo = CurrentBar - tmpRay.StartAnchor.DrawnOnBar + 1; // When did the ray being removed start? Had to account for strength
          Draw.Line(this, "highLine"+(CurrentBar - uiBarsAgo), false, uiBarsAgo, tmpRay.StartAnchor.Price, 0, tmpRay.StartAnchor.Price, Brushes.Red, DashStyleHelper.Dot, LineWidth);
          }
          
          swingHighRays.Pop();
          
          if ( swingHighRays.Count != 0 )
          {
          tmpRay = (Ray)swingHighRays.Peek();
          }
          }
          I wanted to see if this would do anything before adding on any other conditions and when it didn't work, I added the Prints and Draw.Dot to see if anything was happening. I checked the output and the swing high count and start anchor price seems to be right/ makes sense, but for the Close value it just says "NinjaTrader.NinjaScript.PriceSeries". The following is an example of what the output looked like.

          swing high count 1
          Start anchor price 4444.25
          Close value NinjaTrader.NinjaScript.PriceSeries

          What kind of value is the "Close" supposed to be giving me?

          Comment


            #6
            Hello again,
            After some tinkering, although I couldn't get the code to work consistently, I did manage to get it to work on a few bars here and there. Unfortunately based on what I see, this solution is not what I'm looking for. It looks like the CrossAbove and CrossBelow methods will trigger as long as prices go above/below my line but I only want it to trigger if the body of the bar crosses. So if the wicks cross my line, I don't want the line to be removed yet. Sorry if I wasn't clear on my needs from the previous posts.

            Is there perhaps a different solution that could push me towards the right direction?

            Thank you

            Comment


              #7
              Hello timoting,

              For that type of condition you would need to include all of the price values of the bar. You would essentially need to check that the low and open are less than the price and the high and close are above the price.



              Code:
              double price = tmpRay.StartAnchor.Price;
              if(Low[0] < price && Open[0] < price && High[0] > price && Close[0] > price)
              Something like this would potentially work, you would need to take a look at the specific bar values at a time when you see crossing and make sure that the condition fits what the bar values would be. If that fits you could form a price condition like this to check if parts of the bar are above or below the target price.

              I look forward to being of further assistance.
              JesseNinjaTrader Customer Service

              Comment


                #8
                Hello Jesse,

                Thank you for the new suggestion. I tried what you suggested but couldn't get it to work. I'm trying to get rid of the while loop that was originally in the script and when I do, I keep getting the error

                Indicator 'ResistanceTest': Error on calling 'OnBarUpdate' method on bar 2: Object reference not set to an instance of an object.

                I've narrowed it down to the tmpRay.StartAnchor.Price part of the code that's giving me the issue. I'm not sure why though but it looks there were no errors when tmpRay.StartAnchor.Price was used in the while loop. But when I try to declare it like you suggested or just use it in the if loop, I get that error.

                Any suggestions?

                Code:
                ///Resistance
                if(currentBarStatus == bearish && previousBarStatus == bullish && Open[0] == Close[1])
                {
                Ray newRay = Draw.Ray(this, "highRay" + CurrentBar, false, 1, Open[0], 0, Open[0], SwingHighColor, DashStyleHelper.Dash, LineWidth);
                swingHighRays.Push(newRay);
                }
                
                
                
                // Check the break of some swing
                // High swings first...
                Ray tmpRay = null;
                
                if ( swingHighRays.Count != 0 )
                {
                tmpRay = (Ray)swingHighRays.Peek();
                }
                
                Print("line 123 working");
                double price = tmpRay.StartAnchor.Price;
                if(Low[0] < price && Open[0] < price && High[0] > price && Close[0] > price)
                {
                Print("If loop is working");
                
                
                RemoveDrawObject(tmpRay.Tag);
                
                
                if ( KeepBrokenLines )
                { // Draw a line for the broken swing
                int uiBarsAgo = CurrentBar - tmpRay.StartAnchor.DrawnOnBar + 1; // When did the ray being removed start? Had to account for strength
                Draw.Line(this, "highLine"+(CurrentBar - uiBarsAgo), false, uiBarsAgo, tmpRay.StartAnchor.Price, 0, tmpRay.StartAnchor.Price, Brushes.Red, DashStyleHelper.Dot, LineWidth);
                }
                
                swingHighRays.Pop();
                
                if ( swingHighRays.Count != 0 )
                {
                tmpRay = (Ray)swingHighRays.Peek();
                }
                
                }

                Comment


                  #9
                  Hello timoting,

                  Thank you for the post.

                  The error means that an object was null and if you narrowed it down to tmpRay then it looks like thats likely because you are conditionally adding items to the swingHighRays collection. In some cases swingHighRays has a count greater than 0 but in all cases you try to access tmpRay which may or may not exist.

                  You would likely need to just extend the body of the conditon before that:

                  Code:
                  if ( swingHighRays.Count != 0 )
                  {
                  tmpRay = (Ray)swingHighRays.Peek();
                  
                  
                  Print("line 123 working");
                  double price = tmpRay.StartAnchor.Price;
                  
                  // any code that uses tmpRay
                  
                  }

                  I look forward to being of further assistance.
                  JesseNinjaTrader Customer Service

                  Comment


                    #10
                    Hello Jesse,

                    Ahh yes, thank you. I actually figured that out last night and then realized that part of the code is actually what's causing all my problems and not the conditions from before. I think the logic doesn't seem to be working for what I want since some of the lines get forgotten when a new line gets added during the same time it's supposed to be removed. Rather than looking at the top of the stack with Peek, I think I need to be able to look through the whole stack and compare the price of them all to the conditions or something. Is there a way to do that with stacks?

                    Comment


                      #11
                      Hello timoting,

                      You can use any C# collections like a List or Array so that you could use loops or indexes. If you have multiple items in the collection you may need to use a loop to go through them.

                      I look forward to being of further assistance.
                      JesseNinjaTrader Customer Service

                      Comment


                        #12
                        Hello Jesse,

                        Thank you for all your help. I ended up finding a much easier approach to my problem and that was to cycle through the drawobjects on the chart and find all the Rays that have been drawn and to use that to continue on with the rest of my code. For some reason, I just couldn't get the logic of lists correctly but this way seems to work for what I want. Is there any reason I shouldn't be doing it this way? Or rather are there any benefits to using Lists or Arrays? Performance / efficiency maybe?

                        But I do have a different question now that the main coding part is done. Is there any way to get the Opacity of the drawn Ray to be set by the user? I'm talking about the properties area like in the screenshot that I've attached.

                        The code for my drawing is as follows right now.

                        Draw.Ray(this, "lowRay" + CurrentBar, false, 1, Close[0], 0, Close[0], LineColor, DashStyleHelper.Solid, LineWidth);



                        Thank you
                        Attached Files

                        Comment


                          #13
                          Hello timoting,

                          If what you found to work is working for the use case then I don't see any issue with that. If you are using the drawing objects collection that will only work in realtime so if that fits your use case then it should be fine to use that. I could't really make any suggestions on performance as I don't know what code you ended up with but you can use the NinjaScript utilization monitor to observe the scripts performance and try different approaches to see what is the best.

                          In the user interface there is not currently an opacity setting like you pictured, you would need to select one of the brushes which can include some with transparency from the skins. To make a custom brush with an opacity to pass to the drawn object you could see the following link: https://ninjatrader.com/support/help...gcustombrushes
                          In short if you create a brush with opacity it needs to be frozen. You could make a custom user input for an opacity amount and then build a brush with that amount and pass it to the drawing object.


                          I look forward to being of further assistance.

                          JesseNinjaTrader Customer Service

                          Comment


                            #14
                            Hello Jesse,

                            Thank you for your reply.
                            I actually found a major flaw in my coding right now and that is I can no longer use Rays since my code is looking for all Rays on the chart. Is there a way to filter out the Rays with the tag of the Rays that are drawn?

                            I have the following code right now.


                            Code:
                            Draw.Ray(this, "highRay" + CurrentBar, false, 1, Open[0], 0, Open[0], LineColor, DashStyleHelper.Solid, LineWidth);
                            
                            
                            foreach (DrawingTool draw in DrawObjects.ToList())
                            {
                               if (draw is DrawingTools.Ray)
                               {
                               DrawingTools.Ray drawRay = draw as DrawingTools.Ray;
                               if (statement here is true)
                               {
                                  do something
                               }
                            }
                            Can I somehow put in a statement that goes like " if ray's tag includes highRay then do this". In the DrawObjects help page, there are examples for finding specific tags but I'm not looking for just 1 specific tag.

                            Also for the opacity setting that you suggested, would there still be a way for the user to pick the color, or will the color have to be hardcoded now with only the opacity amount coming through as a custom user input?

                            Comment


                              #15
                              Hello timoting,

                              Yes you can use the Tag property from the object, all objects have Tag. If you are not making a unique tag there would not really be a way to find the unique object. You can use any C# means to search the tag like .Cointains("");

                              I look forward to being of further assistance.
                              JesseNinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by algospoke, Yesterday, 06:40 PM
                              2 responses
                              19 views
                              0 likes
                              Last Post algospoke  
                              Started by ghoul, Today, 06:02 PM
                              3 responses
                              14 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by jeronymite, 04-12-2024, 04:26 PM
                              3 responses
                              45 views
                              0 likes
                              Last Post jeronymite  
                              Started by Barry Milan, Yesterday, 10:35 PM
                              7 responses
                              20 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by AttiM, 02-14-2024, 05:20 PM
                              10 responses
                              181 views
                              0 likes
                              Last Post jeronymite  
                              Working...
                              X