I have written a tool (indicator) that helps user to draw some objects on chart, so objects are drawn by indicator, I want objects remain on chart when user changes timeframe of chart from upper toolbar, or even if user decide to remove indicator from chart, is this possible?
Announcement
Collapse
No announcement yet.
Partner 728x90
Collapse
NinjaTrader
Avoid removing of objects drawn by indicator when user change timeframe of chart
Collapse
X
-
Avoid removing of objects drawn by indicator when user change timeframe of chart
Hello
I have written a tool (indicator) that helps user to draw some objects on chart, so objects are drawn by indicator, I want objects remain on chart when user changes timeframe of chart from upper toolbar, or even if user decide to remove indicator from chart, is this possible?
Tags: None
-
Hello tidicofx,
Thank you for your post.
Drawing objects drawn by an indicator will still appear on the chart even after changing the timeframe, although since the scale has been changed they may appear smaller/bigger.
This sample script below demonstrates using drawing objects. When testing out this script by changing the timeframe, I am still able to see the drawing objects on the chart.
Unfortunately, it would not be possible to keep the drawing objects on the chart if you remove the indicator they were drawn by. Removing the indicator will also cause any drawing objects it created to be removed from the chart as well.
Please let us know if you have any further questions.
-
hello, thank you for your reply
i have tested again
here is a line drawn by indicator
then i switch to M10
line is gone
even when i switch back to M15, line is not there
maybe I set something wrong in indicator code?
here is indicator code
Code:private string pid = "PS_"; private SimpleFont myFont; private bool isFirstRun=true; private double pointSize=1; private int digits=0; private double ask=0, bid=0; private bool isCliked = false; private int selectedCandleIdx = -1; private Key priceToDraw = Key.N; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"DrawHorizontalRay"; Name = "DrawHorizontalRay"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = false; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; AllowRemovalOfDrawObjects = 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; LineColor = Brushes.Red; LineStyle = DashStyleHelper.Solid; LineWidth = 2; myFont = new SimpleFont("Arial", 12); } else if (State == State.DataLoaded) { if (ChartPanel!=null) ChartPanel.KeyDown+=new System.Windows.Input.KeyEventHandler(OnKeyDown); if (ChartPanel!=null) ChartPanel.MouseDown+=new System.Windows.Input.MouseButtonEventHandler(OnMouseDown); } else if (State == State.Terminated) { if (ChartPanel!=null) ChartPanel.KeyDown-=new System.Windows.Input.KeyEventHandler(OnKeyDown); if (ChartPanel!=null) ChartPanel.MouseDown-=new System.Windows.Input.MouseButtonEventHandler(OnMouseDown); } } protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (isCliked) { isCliked=false; int x = chartControl.MouseDownPoint.X.ConvertToHorizontalPixels(chartControl.PresentationSource); int y = chartControl.MouseDownPoint.Y.ConvertToVerticalPixels(chartControl.PresentationSource); int barIdx = ChartBars.GetBarIdxByX(chartControl, x); double price = chartScale.GetValueByY((float)y); double high=Bars.GetHigh(barIdx); double low=Bars.GetLow(barIdx); if (price>=low && price<=high) { selectedCandleIdx=barIdx; priceToDraw=0; DateTime dt=Bars.GetTime(barIdx); Draw.TextFixed(this, "Hint", dt.ToString()+" is selected, Press O,H,L,C to draw line", TextPosition.TopLeft); ForceRefresh(); } else if (selectedCandleIdx!=-1) { selectedCandleIdx=-1; Draw.TextFixed(this, "Hint", "", TextPosition.TopLeft); ForceRefresh(); } } if (priceToDraw!=Key.N && selectedCandleIdx!=-1) { DateTime dt=Bars.GetTime(selectedCandleIdx); double price=0; if (priceToDraw==Key.O) price=Bars.GetOpen(selectedCandleIdx); if (priceToDraw==Key.H) price=Bars.GetHigh(selectedCandleIdx); if (priceToDraw==Key.L) price=Bars.GetLow(selectedCandleIdx); if (priceToDraw==Key.C) price=Bars.GetClose(selectedCandleIdx); //Draw.Ray(this, pid+dt.ToString()+"_"+priceToDraw.ToString(), false, dt, price, dt.AddDays(1), price, LineColor, LineStyle, LineWidth); Draw.Line(this, pid+dt.ToString()+"_"+priceToDraw.ToString(), false, dt, price, dt.AddDays(30), price, LineColor, LineStyle, LineWidth); priceToDraw=Key.N; ForceRefresh(); } } protected override void OnBarUpdate() { //Add your custom indicator logic here. if (isFirstRun && CurrentBar>=10) { isFirstRun=false; digits=GetDidgits(); pointSize=GetPoint(); //Draw.TextFixed(this, "Test", digits.ToString()+", "+pointSize.ToString(), TextPosition.BottomLeft); } ask=GetCurrentAsk(); bid=GetCurrentBid(); } public void OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key==Key.O || e.Key==Key.H || e.Key==Key.L || e.Key==Key.C) { e.Handled = true; priceToDraw = e.Key; ForceRefresh(); } } public void OnMouseDown(object sender, System.Windows.Input.MouseEventArgs e) { if (e.LeftButton==MouseButtonState.Pressed) { isCliked = true; ForceRefresh(); } }
Comment
-
Hello tidicofx,
Thank you for your response.
It looks like you are using drawing objects from OnRender. OnRender is used for custom rendering shapes and lines, I would not suggest creating Drawing objects from OnRender. Drawing tools should be used from OnBarUpdate().
If you draw a line from OnBarUpdate(), are you still seeing this behavior occur?
I look forward to your response.
Comment
-
ok, I think I made confusion writing code into OnRenderOriginally posted by NinjaTrader_Gaby View PostHello tidicofx,
Thank you for your response.
It looks like you are using drawing objects from OnRender. OnRender is used for custom rendering shapes and lines, I would not suggest creating Drawing objects from OnRender. Drawing tools should be used from OnBarUpdate().
If you draw a line from OnBarUpdate(), are you still seeing this behavior occur?
I look forward to your response.
I have updated code to make more sense of what I am doing
user clicks on a candle, then press one of Keys O,H,L,C and indicator draws line from selected candle HOLC, very simple example
here is code
still with this code when I change timeframe line is removing from chartCode:private string pid = "PS_"; private SimpleFont myFont; private bool isFirstRun=true; private double pointSize=1; private int digits=0; private double ask=0, bid=0; private bool isCliked = false; private int selectedCandleIdx = -1; private double myChartMin; private double myChartMax; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"DrawHorizontalRay"; Name = "DrawHorizontalRay"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = false; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; AllowRemovalOfDrawObjects = 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; LineColor = Brushes.Red; LineStyle = DashStyleHelper.Solid; LineWidth = 2; myFont = new SimpleFont("Arial", 12); myChartMax = 0; myChartMin = 0; } else if (State == State.DataLoaded) { if (ChartPanel!=null) ChartPanel.KeyDown+=new System.Windows.Input.KeyEventHandler(OnKeyDown); if (ChartPanel!=null) ChartPanel.MouseDown+=new System.Windows.Input.MouseButtonEventHandler(OnMouseDown); } else if (State == State.Terminated) { if (ChartPanel!=null) ChartPanel.KeyDown-=OnKeyDown; if (ChartPanel!=null) ChartPanel.MouseDown-=OnMouseDown; } } protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { myChartMax=chartScale.MaxValue; myChartMin=chartScale.MinValue; } public void OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (selectedCandleIdx!=-1) if (e.Key==Key.O || e.Key==Key.H || e.Key==Key.L || e.Key==Key.C) { DateTime dt=Bars.GetTime(selectedCandleIdx); double price=0; if (e.Key==Key.O) price=Bars.GetOpen(selectedCandleIdx); if (e.Key==Key.H) price=Bars.GetHigh(selectedCandleIdx); if (e.Key==Key.L) price=Bars.GetLow(selectedCandleIdx); if (e.Key==Key.C) price=Bars.GetClose(selectedCandleIdx); Print(dt.ToString()+", "+price.ToString()); Draw.Line(this, pid+dt.ToString()+"_"+e.Key.ToString(), false, dt, price, dt.AddDays(30), price, LineColor, LineStyle, LineWidth); e.Handled = true; ForceRefresh(); } } public void OnMouseDown(object sender, System.Windows.Input.MouseEventArgs e) { if (e.LeftButton==MouseButtonState.Pressed && ChartControl!=null) { //Draw.TextFixed(this, "Test", myChartMax.ToString()+", "+myChartMin.ToString(), TextPosition.TopLeft); int x = ChartControl.MouseDownPoint.X.ConvertToHorizontalPixels(ChartControl.PresentationSource); int y = ChartControl.MouseDownPoint.Y.ConvertToVerticalPixels(ChartControl.PresentationSource); int barIdx = ChartBars.GetBarIdxByX(ChartControl, x); double price = GetPriceFromY(y); double high=Bars.GetHigh(barIdx); double low=Bars.GetLow(barIdx); if (price>=low && price<=high) { selectedCandleIdx=barIdx; Print(selectedCandleIdx.ToString()); DateTime dt=Bars.GetTime(barIdx); Draw.TextFixed(this, "Hint", dt.ToString()+" is selected, Press O,H,L,C to draw line", TextPosition.TopLeft); ForceRefresh(); } else if (selectedCandleIdx!=-1) { selectedCandleIdx=-1; Draw.TextFixed(this, "Hint", "", TextPosition.TopLeft); ForceRefresh(); } } } protected override void OnBarUpdate() { //Add your custom indicator logic here. } private double GetPriceFromY(int y) { if (myChartMax==0 || myChartMin==0 || ChartPanel==null) return (0); return (myChartMax-y*1.0/ChartPanel.H*(myChartMax-myChartMin)); }
Comment
-
Hello tidicofx,
Thank you for your response.
This is because the drawing objects are only created when an onkeydown() or onmousedown() event happens in your script.
When you change the timeframe or data series of the chart, the script is recalculated so the drawing objects disappear. When a drawing object is drawn from OnBarUpdate(), the script can redraw the drawing object based on historical data once the script is reloaded. However, since you are not drawing the objects from OnBarUpdate() they are not re-drawn.
If you would like to have the objects redrawn whenever the script is reloaded/data series or time frame is changed, you can write the drawing object's time and prices to a text file when the script draws something, then reload that file when the script loads so it can then redraw them using OnBarUpdate().
The sample scripts below demonstrate reading and writing to/from a text file:
Please let me know if you have any further questions.
Comment
-
ok, so as far as I understand from your comments, objects will always remove when chart timeframe is changing, I have to track record of drawn objects and redraw them againOriginally posted by NinjaTrader_Gaby View PostHello tidicofx,
Thank you for your response.
This is because the drawing objects are only created when an onkeydown() or onmousedown() event happens in your script.
When you change the timeframe or data series of the chart, the script is recalculated so the drawing objects disappear. When a drawing object is drawn from OnBarUpdate(), the script can redraw the drawing object based on historical data once the script is reloaded. However, since you are not drawing the objects from OnBarUpdate() they are not re-drawn.
If you would like to have the objects redrawn whenever the script is reloaded/data series or time frame is changed, you can write the drawing object's time and prices to a text file when the script draws something, then reload that file when the script loads so it can then redraw them using OnBarUpdate().
The sample scripts below demonstrate reading and writing to/from a text file:
Please let me know if you have any further questions.
this is despite manually drawn objects that remain on chart even when I change timeframe, that's a bit disappointing, hope in future releases of NT that can be considered as option to not remove drawings while indicator is not removed from chart
Comment
-
Hello,
Yes, whenever you change the time frame, data series, or refresh historical data the script is recalculated/reloaded as well so any drawing objects drawn by the strategy will be removed.
Since your drawing objects are outside of OnBarUpdate(), once the script is recalculated they can't be redrawn using historical data - they will only be redrawn when onkeydown() or onmousedown() event happens.
While the indicator is technically not being removed from the chart (like manually removing it from the Indicators window), the script is being reloaded when you change the time frame which means everything in the script is going to be recalculated from scratch.
Please let me know if you have any further questions.
Comment
-
it's clear now, thanksOriginally posted by NinjaTrader_Gaby View PostHello,
Yes, whenever you change the time frame, data series, or refresh historical data the script is recalculated/reloaded as well so any drawing objects drawn by the strategy will be removed.
Since your drawing objects are outside of OnBarUpdate(), once the script is recalculated they can't be redrawn using historical data - they will only be redrawn when onkeydown() or onmousedown() event happens.
While the indicator is technically not being removed from the chart (like manually removing it from the Indicators window), the script is being reloaded when you change the time frame which means everything in the script is going to be recalculated from scratch.
Please let me know if you have any further questions.
Comment
Latest Posts
Collapse
| Topics | Statistics | Last Post | ||
|---|---|---|---|---|
|
Started by Geovanny Suaza, 02-11-2026, 06:32 PM
|
0 responses
576 views
0 likes
|
Last Post
|
||
|
Started by Geovanny Suaza, 02-11-2026, 05:51 PM
|
0 responses
334 views
1 like
|
Last Post
|
||
|
Started by Mindset, 02-09-2026, 11:44 AM
|
0 responses
101 views
0 likes
|
Last Post
by Mindset
02-09-2026, 11:44 AM
|
||
|
Started by Geovanny Suaza, 02-02-2026, 12:30 PM
|
0 responses
553 views
1 like
|
Last Post
|
||
|
Started by RFrosty, 01-28-2026, 06:49 PM
|
0 responses
551 views
1 like
|
Last Post
by RFrosty
01-28-2026, 06:49 PM
|

Comment