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

Trading Hours, Sessions, Draw Vertical Line, Scripting

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

    Trading Hours, Sessions, Draw Vertical Line, Scripting

    I want to develop an indicator that will read my custom Trading Hours collection, and then draw a vertical line at each time (start, end). My custom sessions would include pre-market, RTH open +1 hour, london close, etc

    So far my research on existing indicator searches has come up empty.

    So I starting to read the help file,


    it appears I would need to get the Sessions Collection, loop thru it to find the start and end times of each session...

    but then what?

    Would I need to use the event OnBarUpdate to iterate thru the entire historical bars dataset, comparing each bar's date and timestamp to see if it matches a session start or end date & time adn then call a method to draw a vertical line at that spot? That seems like too much processor work. Is there a better concept?



    whoa, while typing a tag, it was suggested to use "session lines", so i searched for that and found an example script from Jessica P, which contains something like this:

    Code:
    protected override void OnBarUpdate()
            {
    
    if (Bars.FirstBarOfSession)
    			{
    				DrawHorizontalLine("lineSet" + ++lineSet, resistanceLow(ToTime(Time[0])), Color.Aqua);
     ...
    that seems much easier.

    and for my purpose, i just draw a Vertical Line instead. It appears I would use method

    Code:
    Draw.VerticalLine(NinjaScriptBase owner, string tag, int barsAgo, Brush brush, DashStyleHelper dashStyle, int width, bool drawOnPricePanel)
    Is there a way to draw a vertical line that will span ALL panels within a chart object?

    #2
    Hello balltrader, and thank you for your question. I am glad the code sample I posted previously was useful to you.

    The only way to draw a line that spans every panel would be to add the same indicator plotting a vertical line in the same place into every panel.

    As to why this is the case, here is some recent discussion between my colleague Chelsea and another user on the subject of one indicator drawing to multiple panels.



    The limiting factor is that we do not know how many chart panels there are until rendering - see this code sample



    And we need to do things like create every plot well before rendering occurs. If you knew for a fact how many panels a chart was going to have in advance you could hypothetically, from a strategy, create that many indicators, set their PanelU appropriately, then add them using AddChartIndicator. However, as this code would be inflexible and fragile enough to require maintenance, this must be left up to individual developers to implement, and so the only solution I can recommend is to use multiple copies of an indicator in every panel.
    Jessica P.NinjaTrader Customer Service

    Comment


      #3
      added

      thanks, let's ignore the multi-panel question for now.

      is your example the best way to plot this vertical line? so every bar update, it will check this property and set a line to plot during rendering cycle? what if the chart is being updated on every tick, this seems wasteful. is there a better way to set a private var to be used as a bool flag, and if the bar is the start of a session, and the line has been set to be plotted, then skip that section of the code until the next bar starts?

      and if the chart has a data source that uses ticks or other non-time based counters to start a new bar, it shouldn't matter because the bar is generated based on the accumulation of a specific qty of ticks, not time, so if 4 bars are plotted within the first minute of a session [ ], it won't plot 4 vertical lines for each of those 4 bars because they are all within the same minute of the start of the session?

      in your example, you reference a DrawHorizontalLine, which must be a user defined method, because it is not listed in the help reference, correct?

      So in OOP, an object such as a bar can have a property that is a method that can be triggered on an event, like bar update? that makes it much easier.

      thanks,
      Last edited by balltrader; 03-03-2017, 04:09 PM. Reason: addendum

      Comment


        #4
        Data Series Property: Trading Hours Break Line

        Wait.

        In Data Series, Property Window, Trading hours break line....

        this is drawn across all panels, basically the window height.

        so this does what I want.

        All I needed to do was to edit the Trading Hours Session collection, delete the full day, then add new sessions with the start and stop, inserting the new start and stop times, and editing the full day row, and marking the last row of that day as the EOD. Now I can set the break line for all, and it does draw a vertical dividing line at that time and across all panels.

        however, the vertical lines are not drawn in the spots matching the tiemstamps at the bottom of the chart window when I'm using a 4000 tick bar for /ES, but they are close enough.

        I noticed the session mgr does not have the option to "name" a session row, such as "pre-market". but I could detect the session item properties in code and construct a name for use in resetting values in an indicator script...

        is there a coding example of how an indicator would reset its values when a session changes, and not just at EOD?

        thanks

        Comment


          #5
          drawing rectangles

          back to the coding of drawing...

          the session lines are all the same color, so now i'm thinking:

          i could simply draw colored rectangles in a dedicated panel to mark session start and stop times, and that would be a great indication without cluttering up the entire chart and all panels.

          Draw.Rectangle(NinjaScriptBase owner, string tag, DateTime startTime, double startY, DateTime endTime, double endY, bool isGlobal, string templateName)

          could i use this method to draw a rectangle to mark a session start and stop time? would it be able to figure out where to draw the right edge of the rectangle based on endTime if I am using a TICK chart, does NT just extrapolate into the future to the best guess, until that actual time arrives on a tick bar?

          Comment


            #6
            Thank you for your additional questions.

            Is your example the best way to plot this vertical line?
            I realize you found EOD lines later on and a different approach, but for completeness, I wanted to draw your attention to Draw.VerticalLine



            Regarding when to do this, and your questions regarding non-time based series, in addition to using Bars.IsFirstBarOfSession to limit processing this code to the first bar of a session, I'd also like to recommend reviewing Bars.GetBar(DateTime time), as this will give you time axis coordinates using any time directly in a single step.



            So in OOP, an object such as a bar can have a property that is a method that can be triggered on an event, like bar update? that makes it much easier.
            Methods are first-class objects in C#. In NT8 there is an additional consideration when triggering events : any object is only allowed to access other objects in its own thread. This can make coding complicated in some languages. Fortunately, C# has a class called Dispatcher which they document in this publicly available C# documentation here,



            Essentially, what you can do with this method is take any threaded object to start with, call its Dispatcher, and pass it a method, and the method will be called with full access to the selected object's memory. This greatly simplifies multithreaded programming. There is a special thread called the main GUI thread, and if you would like to ignore any advanced programming topics that surround threading and just make any memory you'd like to use available from a global, static context, you can use code like this to dispatch to the main GUI thread :

            Code:
            [FONT=Courier New]        /// <summary>[/FONT]
            [FONT=Courier New]        /// Shows a pop-up from the main thread.[/FONT]
            [FONT=Courier New]        /// </summary>[/FONT]
            [FONT=Courier New]        /// <param name="message">message to show in the pop-up</param>[/FONT]
            [FONT=Courier New]        private static void ShowPopup(string message)[/FONT]
            [FONT=Courier New]        {[/FONT]
            [FONT=Courier New]            Application.Current.Dispatcher.Invoke((Action)(() => {ShowPopupHelper(message);}));[/FONT]
            [FONT=Courier New]        }[/FONT]
            [FONT=Courier New]        private static void ShowPopupHelper(string message)[/FONT]
            [FONT=Courier New]        {[/FONT]
            [FONT=Courier New]            // We'll leave this commented out to avoid annoyance, it's only an example[/FONT]
            [FONT=Courier New]            // which shows we can communicate with the main UI thread[/FONT]
            [FONT=Courier New]            //MessageBoxResult result = MessageBox.Show(message, "OK", MessageBoxButton.YesNo);[/FONT]
            [FONT=Courier New][FONT=Courier New]        }[/FONT]
            [/FONT]
            Here you can see that the ShowPopupHelper method is passed as an object to the main GUI thread's dispatcher.

            Code:
            is there a coding example of how an indicator would reset its values when a session changes, and not just at EOD?
            Bars.IsFirstBarOfSession should be returning true at the beginning of every session. Please let us know if this is not the case.

            Code:
            Draw.Rectangle(NinjaScriptBase owner, string tag, DateTime startTime, double startY, DateTime endTime, double endY, bool isGlobal, string templateName)
            
            could i use this method to draw a rectangle to mark a session start and stop time?
            Yes. However I believe Draw.VerticalLine may be easier for your purposes.

            Code:
            could i use this method to draw a rectangle to mark a session start and stop time?
            Yes. This is why I suggested using Bars.GetBar earlier. If you know your session starts at 8:30 in the morning, for instance, you can use

            Code:
            Bars.GetBar(Time[0].Year, Time[0].Month, Time[0].Day, 8, 30, 0)
            to get the bar index of the bar at 8:30 in the morning. To retrieve DateTimes for each session, I recommend reviewing the code sample here, which loops through each session and gives you beginning and ending times.

            Jessica P.NinjaTrader 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
            21 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