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

replacing Draw.Line by AddPlot

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

    replacing Draw.Line by AddPlot

    Hello everybody,

    I am using the indicator "Repeater V2.2" which uses following code for drawing a horizontal line
    Code:
    Draw.Line(this, label[i]+"Lower", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,1], MySessionIterator.ActualSessionEnd, startStopPrice[i,1], brushColor[i], DashStyleHelper.Dot, 1);
    Unfortunately this line is not selectable as a condition in strategy builder. I've found out that in this case the indicator used for the condition needs to have a plot. In my understanding this is not the case here because a simple "Draw.Line" is used, that's why it's not selectable in Strategy builder. Now I'm wondering how to convert this line to a AddPlot code? I tried following but this doesn't work because I don't get the line plotted any more.
    Code:
    [...]
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    AddPlot(new Stroke (Brushes.Green, DashStyleHelper.Dash, 2), PlotStyle.Line, "lower_horiz_line");
    }
    
    [...]
    
    protected override void OnBarUpdate()
    
    // Draw.Line(this, label[i]+"Lower", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,1], MySessionIterator.ActualSessionEnd, startStopPrice[i,1], brushColor[i], DashStyleHelper.Dot, 1);
    lower_horiz_line[0] = startStopPrice[i,1];
    
    [...]
    
    #region Properties
    [Browsable(false)]
    [XmlIgnore]
    public Series<double> lower_horiz_line
    {
    get { return Values[0]; }
    }
    
    [...]
    No line plotted. But the lower_horiz_line is selectable now in strategy builder, at least

    anyone can assist?
    Last edited by patricia70; 11-23-2020, 10:20 AM.

    #2
    Hello patricia70,

    Thanks for your post.

    A plot will hold a value for each bar in the data series. Since the Draw.Line draws from the calculated opening range, I may suggest saving the price level used with Draw.Line to a variable, and then you can assign the variable's value to the plot at the end of the OnBarUpdate method.

    I suggest them also to check when Bars.IsFirstBarOfSession is true so you can set this variable to 0, or to reset the plot with MyPlot.Reset(). If you set the plot to 0, it can affect the scaling of the chart. You may wish to consider making plots that use Brushes.Transparent to make the plots invisible.

    Series.Reset - https://ninjatrader.com/support/help.../nt8/reset.htm

    Bars.IsFirstBarOfSession - https://ninjatrader.com/support/help...rofsession.htm

    We look forward to assisting.
    JimNinjaTrader Customer Service

    Comment


      #3
      Hi Jim and thanks for your reply. Unfortunately I cannot get it to work. Still trying to understand and doing some tests ...
      Last edited by patricia70; 11-23-2020, 12:57 PM.

      Comment


        #4
        Hello patricia70,

        Thanks for your post.

        I suggest starting small:

        1. Create an indicator that adds 2 plots and has 2 private double variables for "myTop" and "myBottom."

        2. In OnBarUpdate create a condition that sets myTop/myBottom to 0 when Bars.IsFirstBarOfSession is true.

        3. In another condition, check if Close[0] > Open[0], and then set myTop to 500 and myBottom to 400.

        4. Then at the end of OnBarUpdate, assign myTop to Values[0][0] and myBottom to Values[1][0].

        After that, go back to Repeater and do the same thing, except that Step 3 would not be Close[0] > Open[0]. This would instead be where the line gets drawn with Draw.Line.

        If this is too difficult, we could provide some information on NinjaScript Consultants who would be happy to make these modifications for you.

        Let us know if that interests you.
        JimNinjaTrader Customer Service

        Comment


          #5
          Hi Jim and thanks for assistance. The task you explained is understood and fulfilled, see here:
          Code:
          namespace NinjaTrader.NinjaScript.Indicators.IndicatorsTrain ing
          {
          public class OpenRangeSimpleTestTraining1 : Indicator
          {
          private double myTop;
          private double myBottom;
          
          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          Description = @"Enter the description for your new custom Indicator here.";
          Name = "OpenRangeSimpleTestTraining1";
          Calculate = Calculate.OnBarClose;
          IsOverlay = false;
          DisplayInDataBox = true;
          DrawOnPricePanel = true;
          DrawHorizontalGridLines = true;
          DrawVerticalGridLines = true;
          PaintPriceMarkers = true;
          ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
          //Disable this property if your indicator requires custom values that cumulate with each new market data event.
          //See Help Guide for additional information.
          IsSuspendedWhileInactive = true;
          AddPlot(new Stroke(Brushes.Green, DashStyleHelper.Dash, 2), PlotStyle.Line, "myTop");
          AddPlot(new Stroke(Brushes.Red, DashStyleHelper.Dot, 2), PlotStyle.Line, "myBottom");
          }
          else if (State == State.Configure)
          {
          }
          }
          
          protected override void OnBarUpdate()
          {
          if (Bars.IsFirstBarOfSession)
          {
          myTop = 0;
          myBottom = 0;
          }
          
          if (Input[0] > Open[0])
          {
          myTop = 500;
          myBottom = 400;
          }
          
          Values[0][0] = myTop;
          Values[1][0] = myBottom;
          }
          }
          }
          ... but --> my problem is to reflect this to the Repeater indicator. It uses various tools as you certainly know and the one I need in my case is the ToolSelector.OpeningRange. So I used the code block that is already there. In that code block the original Draw.Line is used. In Draw.Line you can specify the start and the end of the drawing. He is drawing from timerange start to timerange end but also extend the line up to session end. In case I would just use

          Values[0][0] = startStopPrice[i,1];

          it won't work as expected.

          Comment


            #6
            Hello patricia70,

            You are almost there. You will want to implement that in the Repeater indicator with the exception of the following

            Consider where you are assigning myTop and myBottom. Instead of assigning them to 500/400 when Input[0] > Open[0], set them to startStopPrice[i,1] and startStopPrice[i,2] when Draw.Line is called.

            We look forward to assisting.
            JimNinjaTrader Customer Service

            Comment


              #7
              But I have disabled/commented that original Draw.Line line, see how it looks like:

              Code:
              protected override void OnBarUpdate()
              
              // Draw.Line(this, label[i]+"Lower", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,1], MySessionIterator.ActualSessionEnd, startStopPrice[i,1], brushColor[i], DashStyleHelper.Dot, 1);
              
              lower_horiz_line[0] = startStopPrice[i,1];
              sorry for getting on your nerves, but I still don't understand

              Comment


                #8
                Hello patricia70,

                You aren't getting on anyone's nerves.

                The changes advised would go into the Repeater script and would not go in a blank script. My suggestion to model in a blank script was so you get an idea on the specific changes that would be needed.

                1. Create your myTop and myBottom variables in Repeater
                2. Create the plots in Repeater
                3. In the if Bars.IsFirstBarOfSession block, reset the myTop and myBottom to 0.
                4. When Draw.Line is called for OpeningRange, assign startStopPrice[i,1] to myTop and startStopPrice[i,2] to myBottom
                5. At the end of the OnBarUpdate method, assign myTop to Values[0][0] and myBottom to Values[1][0]

                I really could not be more helpful here without making the modifications for you. If this is too difficult NinjaScript Consulting services could be considered.
                JimNinjaTrader Customer Service

                Comment


                  #9
                  Ok, got it. Now I was able to use AddPlot and draw the highs and lows.
                  Click image for larger version

Name:	example.png
Views:	545
Size:	11.6 KB
ID:	1129188
                  But unfortunately this is not the result I wanted. Don't get confused from the filled rectangle, this is not important here.

                  I need a horizontal line which would be plotted at the highest high and the lowest low within this time region. That means the line in this example has to be drawn exactly on the upper and lower edge of that violet rectangle. The horizontal lines should be plotted using "AddPlot" and not Draw.Line because I need to access them from a condition in strategy builder as said at the beginning of this topic.

                  is it not possible to have a drawn line as a "plot" in general? let's say I'm evaluating the lows and highs over a time period, let's focus on this example on the lows. The wanted time region starts.

                  1st bar low = 3500
                  2nd bar low = 3503.5
                  3rd bar low = 3502
                  4th bar low = 3499
                  ...
                  10th bar low = 3507

                  when I would place those values into an array bottom_line[0] and using it for "AddPlot" then this wouldn't be a line because the values differ.
                  at bar 3 for example I don't know which the lowest low will be until the time region finishes. So plotting from the beginning this array will result NOT in a horizontal line.

                  So I'm not sure if the AddPlot is the right approach and if so

                  Comment


                    #10
                    Hello patricia70,

                    A plot holds calculated values for each bar in the data series. A line is drawn from one point to another. This indicator draws lines that are at the same price level so they appear horizontal.

                    You could make this Strategy Builder compatible if plots are added and the plot lines hold the the values from the the lines drawn with the drawing tools.

                    The instruction I have provided does just that: Reset the variable we use for the plot line on the first bar of a new session. When Draw.Line is called, we update the variable we want to use for the plots and assign the variable the price level that we give Draw.Line. At the end of OnBarUpdate the variables are assigned to the plot value for the bar slot.

                    You will see something like the attached screenshot and would then know that the plots are projected forward and can be read with the Strategy Builder. We can see that the high and low of the range update (see plot lines) while new highs/lows are seen and the plot is projected forward since we are still plotting with the same value set in the myTop and myBottom variables. You can then reference the plot value for the current bar in the Strategy Builder to get the High/Low calculated from the open range.
                    Attached Files
                    JimNinjaTrader Customer Service

                    Comment


                      #11
                      4. When Draw.Line is called
                      Originally posted by NinjaTrader_Jim View Post
                      [...] When Draw.Line is called, we update the variable we want to use for the plots and assign the variable the price level that we give Draw.Line [...]
                      Instead of assigning them to 500/400 when Input[0] > Open[0], set them to startStopPrice[i,1] and startStopPrice[i,2] when Draw.Line is called.
                      certainly because of my bad english, but I don't understand what you mean by "when Draw.Line is called" Draw.Line is not a function in Repeater2.2 indicator, it's just a command within the if condition block
                      Code:
                      if (toolType[i] == ToolSelector.OpeningRange)
                      {
                      //Draw.Line(this, label[i]+"Lower", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,1], MySessionIterator.ActualSessionEnd, startStopPrice[i,1], brushColor[i], DashStyleHelper.Dot, 1);
                      BOR_lower[0] = startStopPrice[i,1];
                      }
                      [...]
                      This is confusing me. I don't understand how I can assign something within the Draw.Line because first I already commented (and thus disabled) it and second even when I had it in use I am not aware of a technique to assign variables within this Draw.Line... line
                      As you see in the example above I'm already using the if code block where Draw.Line was used. That resulted in the screenshot I posted above in my last post.
                      Last edited by patricia70; 11-24-2020, 01:42 PM.

                      Comment


                        #12
                        Hello patricia70,

                        You want to assign startStopPrice[i,1] to your myTop variable when Draw.Line is called, so within the same condition block. We would not assign this variable within the Draw.Linecall. startStopPrice[i,2] would be assigned to your myBottom variable. Then at the end of OnBarUpdate, myTop and myBottom are assigned to the plots.

                        The Draw.Line call can remain uncommented.

                        If you leave Draw.Line uncommented, assign startStopPrice[i,1] to myTop above the line of code where Draw.Line is called, and then assign myTop to the plot at the end of OnBarUpdate, you will see the same result as post #10. (The same must be done for startStopPrice[i,2] and myBottom.)

                        In post #9 you are showing you are assigning startStopPrice[i,1] to the plot value directly. This would be different that storing that value in a variable and plotting that variable.

                        We look forward to assisting.
                        JimNinjaTrader Customer Service

                        Comment


                          #13
                          thank you Jim for trying to assist. Can you tell me, please ... when you do that as you explained in your post #12. Will this really result in a horizontal (!) line plotted ? The originally existing Draw.Line will be commented and thus disabled for that question.

                          As you see on the screenshot in my post #9 the highs and lows are connected each other. This is not what I want. I want to have a horizontal line. That means that the Plot has to be reset on each bar update so it wont connect points with different values. The value needs to be always the same for the time region.
                          Last edited by patricia70; 11-25-2020, 10:17 AM.

                          Comment


                            #14
                            Hello patricia70,

                            Please see my video below which explains what you would see with Draw.Line commented and uncommented. You may also test the same changes I have made on your end.

                            Demo - https://drive.google.com/file/d/1oDe...w?usp=drivesdk

                            We look forward to assisting.
                            JimNinjaTrader Customer Service

                            Comment


                              #15
                              Dear Jim,

                              first of all I want to express a BIG THANK YOU for the time and your effort you do on assisting me in understanding and getting this to work. Thumbs up, great work with the video demonstration!!! I did it exactly like you but still are not happy with the result. Honestly said, I had it coded exactly like you showed, ok I used other names and color but the logic was the same. To ensure I did not mix up anything in my code I completely removed Repeater2.2 indicator and imported it from scratch so I have the original Repeater code. Then I made the modification according your video so I have it 1:1 like you showed in the demo video. I am using violet color for both upper and bottom range.

                              Why I'm not happy ?

                              1) there is the graphical glitch because of the zero value assignment in IsFirstBar. This is also shown in your demonstration video. Whenever you scroll left next to the startTime the display gets compressed and you loose visibility of the chart. You have to scroll and remain always right of the start time. The chart will display correct only between the correct times. Here's a screenshot how this glitch looks like outside of the desired times when you scroll the schart.
                              Click image for larger version  Name:	glitch.png Views:	0 Size:	456.2 KB ID:	1129480
                              We could mitigate this by removing the zero value assignment from the IsFirstBarOfSession block ...
                              Code:
                              [...]
                              
                              if (Bars.IsFirstBarOfSession)
                              {
                              MySessionIterator.GetNextSession(Time[0], true);
                              //myTop = myBottom = 0 ;
                              
                              [...]
                              and instead of plotting at the end OnBarUpdate, use the plotting in the Draw.Line block ...
                              Code:
                              [...]
                              
                              if (toolType[i] == ToolSelector.OpeningRange)
                              {
                              //Draw.Line(this, label[i]+"Upper", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,1], MySessionIterator.ActualSessionEnd, startStopPrice[i,1], brushColor[i], DashStyleHelper.Dot, 1);
                              //Draw.Line(this, label[i]+"Lower", false, Time[CurrentBar - beginBar[i]], startStopPrice[i,2], MySessionIterator.ActualSessionEnd, startStopPrice[i,2], brushColor[i], DashStyleHelper.Dot, 1);
                              myTop = startStopPrice[i,1];
                              myBottom = startStopPrice[i,2];
                              Values[0][0] = myTop;
                              Values[1][0] = myBottom;
                              
                              [...]
                              
                                       } // end if (daily...
                                    } // end if (Tool...
                                   } //for (i=1; i
                                //Values[0][0] = myTop;
                                //Values[1][0] = myBottom;
                              } // end OnBarUpdate
                              
                              [...]
                              of course this won't produce horizontal lines until session end, it will plot them only within the selected time range (08:00 - 09:00 in this example).
                              Click image for larger version

Name:	noDayExtension.png
Views:	401
Size:	424.2 KB
ID:	1129483


                              2) I don't get 100% horizontal lines from plot start to end. In your demonstration you said you will use 08:00 to 09:00 for the range period. Unfortunately in your video the time 08:00 to 09:00 is not shown completely, the first half is hidden and thus not visible. Especially in the beginning where highs and lows are chaning you will see what happens. I've made two screenshots to demonstrate, that this code won't plot horizontal lines, see here:
                              Click image for larger version  Name:	screenshot.png Views:	0 Size:	7.1 KB ID:	1129481

                              Click image for larger version  Name:	screenshot2.png Views:	0 Size:	430.7 KB ID:	1129482

                              of course the lines always become horizontal towards the end, latest after 09:00 in this example. But at the beginning they are not, because the values settle down according to the highs and lows. That was my problem in understanding and I thought I'm coding something wrong. But with your code shown I get the same result.

                              The goal is to get a clean horizontal line from beginning to the end. Just like repeater2.2 indicator is doing on its original state.

                              any thoughts?
                              Last edited by patricia70; 11-26-2020, 02:38 AM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by bmartz, 03-12-2024, 06:12 AM
                              4 responses
                              32 views
                              0 likes
                              Last Post bmartz
                              by bmartz
                               
                              Started by Aviram Y, Today, 05:29 AM
                              4 responses
                              12 views
                              0 likes
                              Last Post Aviram Y  
                              Started by algospoke, 04-17-2024, 06:40 PM
                              3 responses
                              28 views
                              0 likes
                              Last Post NinjaTrader_Jesse  
                              Started by gentlebenthebear, Today, 01:30 AM
                              1 response
                              8 views
                              0 likes
                              Last Post NinjaTrader_Jesse  
                              Started by cls71, Today, 04:45 AM
                              1 response
                              7 views
                              0 likes
                              Last Post NinjaTrader_ChelseaB  
                              Working...
                              X