NexusFi: Find Your Edge


Home Menu

 





help edit the code Ninja Trader


Discussion in NinjaTrader

Updated
    1. trending_up 818 views
    2. thumb_up 1 thanks given
    3. group 2 followers
    1. forum 2 posts
    2. attach_file 0 attachments




 
Search this Thread
  #1 (permalink)
kirdov1975
Toulon France
 
Posts: 1 since Aug 2022
Thanks Given: 0
Thanks Received: 0

I want to create an indicator that will draw horizontal lines on top and bottom for a given number of ticks on each new candlestick. The code compiled without errors, but the lines do not have a deviation of approximately 8 ticks and are not redrawn. those. new lines do not appear on the new candle, but the old ones continue to hang
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion

namespace NinjaTrader.NinjaScript.Indicators
{
public class CustomHorizontalLines : Indicator
{
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name="Ticks Distance", Description="The number of ticks above and below the opening price to plot horizontal lines", Order=1, GroupName="Parameters")]
public int TicksDistance
{ get; set; }

[NinjaScriptProperty]
[XmlIgnore]
[Display(Name="Line Color", Order=2, GroupName="Parameters")]
public Brush LineColor
{ get; set; }

[Browsable(false)]
public string LineColorSerializable
{
get { return Serialize.BrushToString(LineColor); }
set { LineColor = Serialize.StringToBrush(value); }
}

protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "Draws horizontal lines above and below the opening price based on the specified number of ticks.";
Name = "CustomHorizontalLines";
Calculate = Calculate.OnBarClose;
IsOverlay = true;
DisplayInDataBox = true;
DrawOnPricePanel = true;
DrawHorizontalGridLines = true;
DrawVerticalGridLines = true;
PaintPriceMarkers = true;
ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
IsSuspendedWhileInactive = true;
TicksDistance = 49;
LineColor = Brushes.Gray;
}
}

protected override void OnBarUpdate()
{
if (CurrentBar <= 0)
return;

double openingPrice = Open[0];

double priceAbove = openingPrice + (TicksDistance * TickSize);
double priceBelow = openingPrice - (TicksDistance * TickSize);

// Remove previous horizontal lines
RemoveDrawObject("AboveLine");
RemoveDrawObject("BelowLine");

// Draw horizontal lines above and below the opening price
Draw.HorizontalLine(this, "AboveLine", priceAbove, LineColor);
Draw.HorizontalLine(this, "BelowLine", priceBelow, LineColor);
}
}
}

#region NinjaScript generated code. Neither change nor remove.

namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private CustomHorizontalLines[] cacheCustomHorizontalLines;
public CustomHorizontalLines CustomHorizontalLines(int ticksDistance, Brush lineColor)
{
return CustomHorizontalLines(Input, ticksDistance, lineColor);
}

public CustomHorizontalLines CustomHorizontalLines(ISeries<double> input, int ticksDistance, Brush lineColor)
{
if (cacheCustomHorizontalLines != null)
for (int idx = 0; idx < cacheCustomHorizontalLines.Length; idx++)
if (cacheCustomHorizontalLines[idx] != null && cacheCustomHorizontalLines[idx].TicksDistance == ticksDistance && cacheCustomHorizontalLines[idx].LineColor == lineColor && cacheCustomHorizontalLines[idx].EqualsInput(input))
return cacheCustomHorizontalLines[idx];
return CacheIndicator<CustomHorizontalLines>(new CustomHorizontalLines(){ TicksDistance = ticksDistance, LineColor = lineColor }, input, ref cacheCustomHorizontalLines);
}
}
}

namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.CustomHorizontalLines CustomHorizontalLines(int ticksDistance, Brush lineColor)
{
return indicator.CustomHorizontalLines(Input, ticksDistance, lineColor);
}

public Indicators.CustomHorizontalLines CustomHorizontalLines(ISeries<double> input , int ticksDistance, Brush lineColor)
{
return indicator.CustomHorizontalLines(input, ticksDistance, lineColor);
}
}
}

namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.CustomHorizontalLines CustomHorizontalLines(int ticksDistance, Brush lineColor)
{
return indicator.CustomHorizontalLines(Input, ticksDistance, lineColor);
}

public Indicators.CustomHorizontalLines CustomHorizontalLines(ISeries<double> input , int ticksDistance, Brush lineColor)
{
return indicator.CustomHorizontalLines(input, ticksDistance, lineColor);
}
}
}

#endregion


Reply With Quote

Can you help answer these questions
from other members on NexusFi?
CFTC Rewrites the Rulebook -- Kalshi Cracks $1B Non-Spor …
Prediction Markets & Event Contracts
Without Pulisic, USA 61.5% Live vs. Australia -- France …
Prediction Markets & Event Contracts
Powell in 48 Hours: Word Markets Give 78% on Inflation, …
Prediction Markets & Event Contracts
Fabrication or Framework? Irans Denied MOU Explains the …
Prediction Markets & Event Contracts
Trump Truth Social Fires Hormuz From 10% to 59% -- Arsen …
Prediction Markets & Event Contracts
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Big Mike in Ecuador
205 thanks
Sober Journey With S&P
21 thanks
30 Sessions
20 thanks
Volume Indicators
8 thanks
Thanks Mike. Godspeed.
7 thanks
  #2 (permalink)
 
trendisyourfriend's Avatar
 trendisyourfriend 
Quebec Canada
Legendary Market Wizard
 
Experience: Intermediate
Platform: NinjaTrader
Broker: AMP/CQG
Trading: ES, NQ, YM
Frequency: Daily
Duration: Minutes
Posts: 4,580 since Oct 2009
Thanks Given: 4,267
Thanks Received: 6,202

Have you tried using ...
Calculate = Calculate.OnEachTick; // Change Calculate property to OnEachTick

Also, you do not need the removedrawobject("tagname")

When you post code, use the Code symbol (signe cardinal ou tic-tac-to dans la barre des menus)


Reply With Quote
  #3 (permalink)
 
Fi's Avatar
 Fi 
NexusFi
 



trendisyourfriend View Post
Have you tried using ...
Calculate = Calculate.OnEachTick;

Also, you do not need the removedrawobject("tagname")

@trendisyourfriend,

Good call on OnEachTick -- that's the right fix for live chart responsiveness. OnBarClose on a live chart fires exactly once at bar close, so any price-relative lines are always a full bar behind while price is moving.

One thing worth adding: when you flip to OnEachTick, wrap the draw logic in if(IsFirstTickOfBar) to avoid redundant redraws on every tick:

 
Code
if(IsFirstTickOfBar)
{
    double priceAbove = Open[0] + TicksDistance * TickSize;
    double priceBelow = Open[0] - TicksDistance * TickSize;
    Draw.HorizontalLine(this, "AboveLine", priceAbove, LineColor);
    Draw.HorizontalLine(this, "BelowLine", priceBelow, LineColor);
}
On RemoveDrawObject -- agreed, not needed. Draw.HorizontalLine with a static tag overwrites in place automatically. You'd only need unique tags (like "AboveLine" + CurrentBar) if you wanted lines that don't overwrite each other per candle -- and at that point you'd switch to Draw.Line to get controllable endpoints.

Also worth flagging: if the tick distance still looks off, the TicksDistance default in that code is 49, not 8. Change it in the indicator parameters panel.

The Serialize.BrushToString from NinjaTrader.Gui.Tools is implemented correctly -- that's the standard NT8 serialization pattern for persisting Brush properties between sessions. Leave it alone.

TGIF! Have a good weekend!

-- Fi

"The difference between OnBarClose and OnEachTick is invisible on historical data -- and completely obvious the moment you go live."


Learn more about Fi AI trading companion
IMPORTANT: I can make mistakes! Always verify data before relying on it.

Please leave feedback here. You can disable my ability to reply to your posts by placing me on your ignore list.

Fi provides educational information on a best-effort basis only. You are responsible for your own trading decisions and for verification of all data. This message is not trading advice.
Reply With Quote




Last Updated on June 5, 2026


© 2026 NexusFi®, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Downloads - Top
no new posts