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

Migrating calculations from OR to OBU

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

    Migrating calculations from OR to OBU

    Hey guys,
    In the script below I draw pivot highs in OR

    Code:
            protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
            {
                base.OnRender(chartControl, chartScale);
    
                if (Bars == null || ChartControl == null)
                    return;
    
                SharpDX.Direct2D1.SolidColorBrush textBrushDx = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, new SharpDX.Color(120, 123, 134, 255));
                SharpDX.DirectWrite.TextFormat textFormat1 = new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Globals.DirectWriteFactory, "Arial", FontWeight.Bold, FontStyle.Normal, (float)8);
    
                for(int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
                {
                    //Pivot High
                    if ((High.GetValueAt(barIndex - 1) >= High.GetValueAt(barIndex)) && (High.GetValueAt(barIndex - 1) > High.GetValueAt(barIndex - 2))) //swing high
                    {
                        int x1 = chartControl.GetXByBarIndex(ChartBars, barIndex - 1) - 8;
                        int y1 = chartScale.GetYByValue(High.GetValueAt(barIndex - 1)) - 22;
    
                        SharpDX.Vector2 TextPoint = new SharpDX.Vector2(x1, y1);
    
                        SharpDX.DirectWrite.TextLayout textLayout1 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory, "PH", textFormat1, 400, textFormat1.FontSize);
    
                        RenderTarget.DrawTextLayout(TextPoint, textLayout1, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
    
                    }
                }
            }​
    My question is: how to do the calculations in OBU and leave OR only with the drawings?​

    Code:
    protected override void OnBarUpdate()
            {
                //Pivot High
                if ((High[1] >= High[0]) && (High[1] > High[2]))
                {
                    int x1 = CurrentBar - 1;
                    double y1 = High[1];
                }
            }​
    ?

    #2
    Hello rafaelcoisa,

    Thank you for your post.

    At first glance, it appears that you have properly moved the calculations to OnBarUpdate(). I recommend testing out a modified script that makes this change. If you don't want to make many changes or comment/uncomment a lot of code, you could create a copy for modifying and testing rather than making changes to your existing script. This may be done by right-clicking the existing script in the NinjaScript Editor then selecting Save As. Give the copy script a new name and then feel free to adjust OnBarUpdate() and OnRender() accordingly.

    There is more information about "Precomputing values instead of calculating in OnRender()" on the NinjaScript Best Practices page of the help guide here:


    Please let us know if we may be of further assistance.
    Emily C.NinjaTrader Customer Service

    Comment


      #3
      Hello, @NinjaTrader_Emily.
      I understand what you said. But what I put here:
      Code:
      SharpDX.Vector2 TextPoint = new SharpDX.Vector2(x1, y1);
      ​since the calculation is now in OnBarUpdate?

      Comment


        #4
        Hello rafaelcoisa,

        Thank you for your reply.

        Although you are now calculating x1 and y1 in OnBarUpdate, those values may be used in OnRender for your Vector2 object. You could even set a bool, for example pivotHigh, that is True when the conditions in OnBarUpdate() are true, then use that bool for the code portion in OnRender(). Here is an example based on the snippets you have provided:

        private bool pivotHigh;

        protected override void OnBarUpdate()
        {
        //Pivot High
        if ((High[1] >= High[0]) && (High[1] > High[2]))
        {
        int x1 = CurrentBar - 1;
        double y1 = High[1];
        pivotHigh = true;
        }
        else
        {
        pivotHigh = false;
        }
        }​

        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
        base.OnRender(chartControl, chartScale);

        if (Bars == null || ChartControl == null)
        return;

        SharpDX.Direct2D1.SolidColorBrush textBrushDx = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, new SharpDX.Color(120, 123, 134, 255));
        SharpDX.DirectWrite.TextFormat textFormat1 = new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Gl obals.DirectWriteFactory, "Arial", FontWeight.Bold, FontStyle.Normal, (float)8);

        for(int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
        {
        //Pivot High
        if (pivotHigh) //swing high
        {
        SharpDX.Vector2 TextPoint = new SharpDX.Vector2(x1, y1);

        SharpDX.DirectWrite.TextLayout textLayout1 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Gl obals.DirectWriteFactory, "PH", textFormat1, 400, textFormat1.FontSize);

        RenderTarget.DrawTextLayout(TextPoint, textLayout1, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
        }
        }
        }​​


        Please let us know if we may be of further assistance.​​
        Emily C.NinjaTrader Customer Service

        Comment


          #5
          Thanks @NinjaTrader_Emily.
          I'm drawing now. But there is only one drawing.
          How to make it historical?

          Comment


            #6
            Hello rafaelcoisa,

            Thank you for your reply.

            I see what you are saying; if you remove the use of the bool and keep the original condition in OnRender(), do you see the same results? This is what I am referring to:

            protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
            {
            base.OnRender(chartControl, chartScale);

            if (Bars == null || ChartControl == null)
            return;

            SharpDX.Direct2D1.SolidColorBrush textBrushDx = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, new SharpDX.Color(120, 123, 134, 255));
            SharpDX.DirectWrite.TextFormat textFormat1 = new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Gl obals.DirectWriteFactory, "Arial", FontWeight.Bold, FontStyle.Normal, (float)8);

            for(int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
            {
            //Pivot High
            if (pivotHigh) //swing high change to:
            if ((High.GetValueAt(barIndex - 1) >= High.GetValueAt(barIndex)) && (High.GetValueAt(barIndex - 1) > High.GetValueAt(barIndex - 2))) //swing high
            {
            SharpDX.Vector2 TextPoint = new SharpDX.Vector2(x1, y1);

            SharpDX.DirectWrite.TextLayout textLayout1 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Gl obals.DirectWriteFactory, "PH", textFormat1, 400, textFormat1.FontSize);

            RenderTarget.DrawTextLayout(TextPoint, textLayout1, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
            }
            }
            }​​​

            Thank you for your patience.
            Emily C.NinjaTrader Customer Service

            Comment


              #7
              @NinjaTrader_Emily.
              In the last code you gave me​, there are these two conditions
              Code:
              if ((High[1] >= High[0]) && (High[1] > High[2]))
              and
              Code:
              if ((High.GetValueAt(barIndex - 1) >= High.GetValueAt(barIndex)) && (High.GetValueAt(barIndex - 1) > High.GetValueAt(barIndex - 2)))
              Wouldn't you be calculating the same thing twice, once in OBU and once in OR? My goal is to learn how to calculate in OBU and just draw in OR historically. ​

              Comment


                #8
                Hello rafaelcoisa,

                Thank you for your reply.

                In this scenario, x1 and y1 are variables that are holding values. Those values are still being calculated and saved in OnBarUpdate(). This line of code is a condition that is comparing values:

                Code:
                if ((High.GetValueAt(barIndex - 1) >= High.GetValueAt(barIndex)) && (High.GetValueAt(barIndex - 1) > High.GetValueAt(barIndex - 2)))
                By putting the comparison inside of the following loop, you are already implementing another NinjaScript best practice mentioned in the link I previously shared:

                Code:
                for(int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
                Because of this loop, you are restricting OnRender() calculations to visible ChartBars; if you use Ctrl + F to search this bolded phrase at the following link, you will see
                the example snippet and explanation of why this is a best practice:


                "Why: Rendering should be reserved for rendering on what is visible on the Chart. Performing calculations on bar index which are not visible can cause random spikes in CPU consumption."

                In some cases, calculations or comparisons of different values may be necessary in OnRender(). By limiting the calculations and making sure they are only performed on the visible portion of the chart, you may greatly reduce the resource utilization of the script.

                Please feel free to reach out with any additional questions or concerns.
                Emily C.NinjaTrader Customer Service

                Comment


                  #9
                  @NinjaTrader_Emily.

                  if I run this code:​
                  Code:
                  int x1;
                  double y1;
                  
                  protected override void OnBarUpdate()
                          {
                              if ((High[1] >= High[0]) && (High[1] > High[2]))
                              {
                                  x1 = CurrentBar - 1;
                                  y1 = High[1];
                  
                                  pivotHigh = true;
                              }
                              else
                              {
                                  pivotHigh = false;
                              }
                          }​​
                  
                          protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                          {
                              base.OnRender(chartControl, chartScale);
                  
                              if (Bars == null || ChartControl == null)
                                  return;
                  
                              SharpDX.Direct2D1.SolidColorBrush textBrushDx = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, new SharpDX.Color(120, 123, 134, 255));
                              SharpDX.DirectWrite.TextFormat textFormat1 = new SharpDX.DirectWrite.TextFormat(NinjaTrader.Core.Globals.DirectWriteFactory, "Arial", FontWeight.Bold, FontStyle.Normal, (float)8);
                  
                              for(int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
                              {
                                  if ((High.GetValueAt(barIndex - 1) >= High.GetValueAt(barIndex)) && (High.GetValueAt(barIndex - 1) > High.GetValueAt(barIndex - 2)))
                                  {
                                      int x1R = chartControl.GetXByBarIndex(ChartBars, x1) - 8;
                                      int y1R = chartScale.GetYByValue(y1) - 22;
                  
                                      SharpDX.Vector2 TextPoint = new SharpDX.Vector2(x1R, y1R);
                  
                                      SharpDX.DirectWrite.TextLayout textLayout1 = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory, "PH", textFormat1, 400, textFormat1.FontSize);
                  
                                      RenderTarget.DrawTextLayout(TextPoint, textLayout1, textBrushDx, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
                                  }
                              }
                          }​
                  This is the result:​

                  Click image for larger version

Name:	ES 12-22.png
Views:	130
Size:	4.8 KB
ID:	1223277

                  There is a problem.

                  Comment


                    #10
                    Hello rafaelcoisa,

                    Thank you so much for your patience.

                    I was able to create a sample script that uses Series<bool> pivotHigh, Series<int> x1, and Series<double> y1. These values are saved as a series to save the values needed at each bar index. Then, in the OnRender() method the script loops through the visible bars on the chart and checks if the pivotHigh for that bar index is set to True:
                    Code:
                    if (pivotHigh.GetValueAt(barIndex) == true)
                    If true, then it will draw text using the x1 and y1 values saved in the series for that bar index by setting x1R and y1R to the necessary value:
                    Code:
                    int x1R = chartControl.GetXByBarIndex(ChartBars, x1.GetValueAt(barIndex)) - 8;
                    int y1R = chartScale.GetYByValue(y1.GetValueAt(barIndex)) - 22;
                    OnRenderTextTest_NT8.zip

                    I have exported and attached the script for your reference. Please let me know if I may be of further assistance.​
                    Emily C.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by r68cervera, Today, 05:29 AM
                    0 responses
                    2 views
                    0 likes
                    Last Post r68cervera  
                    Started by geddyisodin, Today, 05:20 AM
                    0 responses
                    3 views
                    0 likes
                    Last Post geddyisodin  
                    Started by JonesJoker, 04-22-2024, 12:23 PM
                    6 responses
                    35 views
                    0 likes
                    Last Post JonesJoker  
                    Started by GussJ, 03-04-2020, 03:11 PM
                    12 responses
                    3,239 views
                    0 likes
                    Last Post Leafcutter  
                    Started by AveryFlynn, Today, 04:57 AM
                    0 responses
                    6 views
                    0 likes
                    Last Post AveryFlynn  
                    Working...
                    X