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!
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
NinjaTrader
Volume Bar Color Alert
Collapse
X
-
Volume Bar Color Alert
I have customized a volume bar color using OnRender with a for loop that determine the color of the bar based on my formula.. My question now is how can i pass each of the volume bar color information so that it can be used in the alert? I am stuck as I can't think of how to store it as a series in onBarUpdate() that can be used in the alert? Any idea, thanks.
Tags: None
-
Hello cyberjames2019,
Thanks for the post.
From the given details it sounds like you may have used OnRender to do your actual calculation which would pose a problem as that has no relation to series or bar data. Generally if you are trying to expose data you would have a Plot and store data to the plot from OnBarUpdate. OnRender could access that data to render it in a custom way. The plot by default is exposed and you can also make a public property to give it a custom name if needed. OnBarUpdate could use the plot data for alerts as well. This type of logic can be found in the Pivots and ZigZag indicators.
I look forward to being of further assistance.JesseNinjaTrader Customer Service
-
Hi Jesse,
Based on your suggestion I have tried the following and I have two questions.
1. I must have two plots to get the series: volume and the color data? the color data then can be used in the alert like below example?
2. How can I permanently set the color of each individual volume bar uniquely using the below example? I need each individual bar to be permanently displaying a unique color based on condition. I can do that in onRender using for loop. How to do it here in onBarUpdate() to call each volume bar brush color?
{
public class VolumeColorBar : Indicator
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Indicator here.";
Name = "VolumeColorBar";
Calculate = Calculate.OnEachTick;
IsOverlay = false;
DisplayInDataBox = true;
DrawOnPricePanel = true;
DrawHorizontalGridLines = true;
DrawVerticalGridLines = true;
PaintPriceMarkers = 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;
AddPlot(new Stroke(Brushes.Orange, 2), PlotStyle.Bar, "VolBar");
AddPlot(new Stroke(Brushes.Orange, 2), PlotStyle.Bar, "VolBarColor");
}
else if (State == State.Configure)
{
}
else if (State == State.DataLoaded)
{
}
}
protected override void OnBarUpdate()
{
//Add your custom indicator logic here.
if(Volume[0] < 100) {
Plots[0].Brush = Brushes.Green;
Values[0][0] = Volume[0];
Values[1][0] = 1; //green
} else if(Volume[0] > 100) {
Plots[0].Brush = Brushes.Yellow;
Values[0][0] = Volume[0];
Values[1][0] = 2; //yellow
}
}
#region Properties
[Browsable(false)]
[XmlIgnore]
public Series<double> VolBar
{
get { return Values[0]; }
}
[Browsable(false)]
[XmlIgnore]
public Series<double> VolBarColor
{
get { return Values[1]; }
}
#endregion
}
}
Thanks
James
Comment
-
Hello cyberjames2019,
1. I must have two plots to get the series: volume and the color data? the color data then can be used in the alert like below example?
. How can I permanently set the color of each individual volume bar uniquely using the below example? I need each individual bar to be permanently displaying a unique color based on condition. I can do that in onRender using for loop. How to do it here in onBarUpdate() to call each volume bar brush color?
I look forward to being of further assistance.
JesseNinjaTrader Customer Service
Comment
-
Hi Jesse,
Below is the for loop in the onRender which I wish to keep this logic. Could you please suggest how I would be able to pass the volBrushDx to onBarUpdate? Please look at the //Volume Bar Color in the for loop.
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
try
{
if( Bars == null || ChartControl == null || Bars.Instrument == null || !IsVisible )
{
return;
}
base.OnRender(chartControl, chartScale);
NinjaTrader.Data.Bars bars = ChartBars.Bars;
//Bar locations
SharpDX.Vector2 point0 = new SharpDX.Vector2();
SharpDX.Vector2 point1 = new SharpDX.Vector2();
float lineWidth;
//bar brushes
SharpDX.Direct2D1.Brush blueBrushDx = BlueVolumeBrush.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush redBrushDx = RedVolumeBrush.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush grayBrushDx = GrayVolumeBrush.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush orangeBrushDx = OrangeVolumeBrush.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush liveBrushDx = Brushes.Purple.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush greenBrushDx = GreenVolumeBrush.ToDxBrush(RenderTarget);
SharpDX.Direct2D1.Brush volBrushDx = null;
SharpDX.Direct2D1.StrokeStyleProperties ssProps = new SharpDX.Direct2D1.StrokeStyleProperties {EndCap = SharpDX.Direct2D1.CapStyle.Round};
SharpDX.Direct2D1.StrokeStyle myStyle = new SharpDX.Direct2D1.StrokeStyle(RenderTarget.Factory , ssProps);
for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex ; idx++)
{
double volValue = bars.GetVolume(idx);
double volValue1 = bars.GetVolume(Math.Max(0, idx - 1));
double volValue2 = bars.GetVolume(Math.Max(0, idx - 2));
double closeValue = bars.GetClose(idx);
double closeValue1 = bars.GetClose(Math.Max(0, idx - 1));
double closeValue2 = bars.GetClose(Math.Max(0, idx - lookback));
//in Pixels
float volY = chartScale.GetYByValue(volValue);
int zeroY = chartScale.GetYByValue(0);
int x = chartControl.GetXByBarIndex(ChartBars, idx);
int myMarginRight = chartControl.CanvasRight;
int rectWidth = myMarginRight - x;
if( idx < 0 || idx >= BarsArray[0].Count )
{
continue;
}
point0.X = x;
point0.Y = volY;
point1.X = x;
point1.Y = zeroY;
//Volume Bar Color
if((closeValue > closeValue2) && (volValue > f.GetValueAt(idx)*z)) {
volBrushDx = greenBrushDx;
} else if((closeValue > closeValue2) && (volValue < f.GetValueAt(idx)*z )) {
volBrushDx = blueBrushDx;
} else if((closeValue < closeValue2) && (volValue < f.GetValueAt(idx)*z)) {
volBrushDx = orangeBrushDx;
} else if((closeValue < closeValue2) && (volValue > f.GetValueAt(idx)*z )) {
volBrushDx = redBrushDx;
} else {
volBrushDx = grayBrushDx;
}
if (volY.CompareTo(zeroY) != 0) // to prevent erroneous plotting of the end caps
{
RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
RenderTarget.DrawLine(point1, point0, volBrushDx , lineWidth, myStyle);
RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased;
}
}
//Values[2][0] = 1;
//Values[2][idx] = 2;
if (volBrushDx != null) volBrushDx.Dispose();
greenBrushDx.Dispose();
blueBrushDx.Dispose();
grayBrushDx.Dispose();
redBrushDx.Dispose();
orangeBrushDx.Dispose();
liveBrushDx.Dispose();
}
catch (Exception)
{}
}
Thanks
James
Comment
-
Hello cyberjames2019,
Thanks for posting that.
From what you have here you can keep your rendering logic and just move your price conditions to OnBarUpdate like you had shown in post #3.
You could use a Plot or a Series for this, either would work. A plot will show up visually so if you wanted the visual Plot you could use that or otherwise a series just to store data. https://ninjatrader.com/support/help...t8/seriest.htm
This is the same concept the pivots and zig zag use, OnBarUpdate is checking price conditions and then OnRender is using the series to color bars.
With this added code your post #3 makes sense, that would be the correct approach as you have moved the price conditions to OnBarUpdate and then set a result to the Plot.
From OnRender you would then use the GetValueAt() method on your Plot instead of Close or Volume.
double plotValue = Values[0].GetValueAt(idx);
You can then make basic conditions in OnRender that check the value of the plot to know if you should color a bar or not. The plot is now also exposed so other scripts can access that data or also so that you can use Alerts from OnBarUpdate at a specific rate.
I look forward to being of further assistance.JesseNinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by cutzpr, Today, 08:54 AM
|
0 responses
6 views
0 likes
|
Last Post
by cutzpr
Today, 08:54 AM
|
||
Started by benmarkal, Today, 08:44 AM
|
0 responses
11 views
0 likes
|
Last Post
by benmarkal
Today, 08:44 AM
|
||
Started by Tin34, Today, 03:30 AM
|
2 responses
26 views
0 likes
|
Last Post
by Tin34
Today, 04:11 AM
|
||
Started by sastrades, Yesterday, 09:59 AM
|
2 responses
41 views
0 likes
|
Last Post Today, 04:06 AM | ||
Started by ETFVoyageur, Today, 12:52 AM
|
1 response
24 views
0 likes
|
Last Post Today, 03:36 AM |
Comment