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

Scroll chart to date (Set "End date") of chart programmatically

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

    Scroll chart to date (Set "End date") of chart programmatically

    is it possible to programmatically jump to specific date as the start/end date, instead of manually inputing by user :


    #2
    Hello ttodua,

    Thanks for your post.

    There are no documented or supported ways to scroll the chart to a specific date or to set the Start Date/End Date programmatically.

    That said, this thread will be open for community members to comment in.

    Let us know if we may assist further.
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      It is possible to scroll the chart to a specific period of time. To do this, you have to get the "scrollBar" control from ChartControl and set the scroll bars "Value".

      I have not yet discovered any way to set a chart's end date. This makes writing tools for reviewing orders taken on past charts very difficult.

      I'd like a feature request to be able to change a chart's viewable range through script. I would expect it to be the equivalent of opening up the UI and setting the controls there as shown in the screen shot of ttodua's post.

      This code snippet, which can be used by indicator's would allow you to scroll to a specific place in a chart.

      Code:
          class Scroller
          {
              public Scroller(Gui.Chart.ChartControl control)
              {
                  if(control == null)
                  {
                      throw new ArgumentNullException("chartControl");
                  }
      
                  chartControl = control;
      
                  chartControl.Dispatcher.InvokeAsync(() =>
                      {
                          scrollBar = control.ChartTab.FindName("scrollBar") as System.Windows.Controls.Primitives.ScrollBar;
                      });
              }
      
              public void ScrollTo(int barIndex)
              {
                  scrollBar.Dispatcher.InvokeAsync(
                      () => { scrollBar.Value = Math.Min(Math.Max(scrollBar.Minimum, barIndex + GetNumberOfVisibleBars()/2), scrollBar.Maximum); });
              }
      
              public void ScrollTo(int barIndex, int offset)
              {
                  scrollBar.Dispatcher.InvokeAsync(
                      () => { scrollBar.Value = Math.Min(Math.Max(scrollBar.Minimum, barIndex + offset), scrollBar.Maximum); });
              }
      
              int GetNumberOfVisibleBars()
              {
                  return (int)scrollBar.LargeChange;
                  //chartControl.PrimaryBars.ToIndex - chartControl.PrimaryBars.FromIndex;
              }
      
      
              Gui.Chart.ChartControl chartControl;
              System.Windows.Controls.Primitives.ScrollBar scrollBar;
          }

      Comment


        #4
        I figured out how to programmatically set the range of a chart.
        • The code below accesses a private function of ChartControl through reflection.
        • It has been tested on charts using only one data series. Modifies the primary data series.
        • Should probably be called from the thread the ChartControl uses for UI. Use ChartControl.Dispatcher.InvokeAsync
        • It will force the chart and all indicators to reload. This is expected behavior as that is also what the UI does when the range is changed
        • RefreshAllBars will REMOVE all drawing objects!!!
        • Calling PropagateInstrument on the the chart will not remove the drawing objects. It also won't remove drawing objects that should not be on screen. For example, consider a the chart is set to 1/2/2020 as the end date and a drawing object (Rectangle) is drawn on the chart. If the chart end date is then set to 1/1/2020 that rectangle will still be present on the chart. This can affect saving of the drawing tool depending on the drawing tool.

        Code:
            public static class ChartControlExtensions
            {
                public static void RefreshAllBars(this ChartControl chartControl)
                {
                    var methodInfo = chartControl.GetType().GetMethod("RefreshAllBars",
                        System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance);
        
        
                    var parameters = new object[]
                        {};
        
                    methodInfo.Invoke(chartControl, null);
                }
        
                public static void SetPrimaryBarRange(this ChartControl chartControl, DateTime from, DateTime to)
                {
                    if(from >= to)
                    {
                        throw new ArgumentException(string.Format("Invalid date range. To:{0} must be after From:{1}.", to, from));
                    }
        
                    var properties = chartControl.PrimaryBars.Properties;
                    properties.RangeType = RangeType.CustomRange;
                    properties.From = from;
                    properties.To = to;
                    properties.From = from;
                    chartControl.RefreshAllBars();
                }
        
                public static void SetPrimaryBarRange(this ChartControl chartControl, int daysToLoad, DateTime to)
                {
                    if(daysToLoad <= 0)
                    {
                        throw new ArgumentException(string.Format("daysToLoad must be >= 0. daysToLoad = ", daysToLoad));
                    }
        
                    var properties = chartControl.PrimaryBars.Properties;
                    properties.RangeType = RangeType.Days;
                    properties.To = to;
                    properties.DaysBack = daysToLoad;
                    chartControl.RefreshAllBars();
                }
        
                public static void SetPrimaryBarRange(this ChartControl chartControl, int daysToLoad)
                {
                    SetPrimaryBarRange(chartControl, daysToLoad, Core.Globals.Now.Date);
                }
        
                public static void SetPrimaryBarRangeByBarCount(this ChartControl chartControl, int barsToLoad, DateTime to)
                {
                    if(barsToLoad <= 0)
                    {
                        throw new ArgumentException(string.Format("daysToLoad must be >= 0. daysToLoad = ", barsToLoad));
                    }
        
                    var properties = chartControl.PrimaryBars.Properties;
                    properties.RangeType = RangeType.Bars;
                    properties.To = to;
                    properties.BarsBack = barsToLoad;
                    chartControl.RefreshAllBars();
                }
        
                public static void SetPrimaryBarRangeByBarCount(this ChartControl chartControl, int barsToLoad)
                {
                    SetPrimaryBarRangeByBarCount(chartControl, barsToLoad, Core.Globals.Now.Date);
                }
        
            }
        Last edited by ntbone; 02-06-2023, 07:49 PM.

        Comment


          #5
          ntbone thanks for sharing the snippet. You seem to be experienced in deeper details of nt. However, my initial request was to 'set start date' in field, not just visually scroll chart to the beggining. for example if chart data starts 2022.01.01 and from indicator I want to set it to be start-date at 2021.08.08

          Comment


            #6
            I shared two different code snippets. The first snippet scrolls to a specific place. The second code snippet does in fact let you set the start date of the chart. While you can call it from an indicator, the chart will get reloaded and the indicator itself will also get reloaded which would cause a loop. I use the code to set the chart range from an addon window that is external to the chart.

            Comment


              #7
              ntbone ah, I see now, thank you for the help! that was I wanted in my case. i'll test when i have time.

              Comment


                #8
                See my comments in post Groups I have discovered some side effects and currently do not have a solution that works without some sort of issue when it comes to drawing objects.

                Comment


                  #9
                  ntbone i cant find your message, can you link? tnx

                  Comment


                    #10
                    ntbone Very nice work on the ChartControlExtensions class !

                    I must say it is B-B-B-B-Bad to the bone


                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by techgetgame, Yesterday, 11:42 PM
                    0 responses
                    8 views
                    0 likes
                    Last Post techgetgame  
                    Started by sephichapdson, Yesterday, 11:36 PM
                    0 responses
                    2 views
                    0 likes
                    Last Post sephichapdson  
                    Started by bortz, 11-06-2023, 08:04 AM
                    47 responses
                    1,615 views
                    0 likes
                    Last Post aligator  
                    Started by jaybedreamin, Yesterday, 05:56 PM
                    0 responses
                    10 views
                    0 likes
                    Last Post jaybedreamin  
                    Started by DJ888, 04-16-2024, 06:09 PM
                    6 responses
                    20 views
                    0 likes
                    Last Post DJ888
                    by DJ888
                     
                    Working...
                    X