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
Add indicator to other indicator in NT8
Collapse
X
-
Hello ninjo,
Thanks for your post.
AddChartIndicator is used for strategies only.
If you would like to add an indicator within an indicator and plot it, I would recommend instantiating the indicator as normal, and then to create another plot in the indicator for the SMA. Then within OnBarUpdate() assign the Value for that plot to be the value from the SMA indicator.
Code:protected override void OnStateChange() { if (State == State.SetDefaults) { AddPlot(Brushes.White, "MyAddedPlot"); } } protected override void OnBarUpdate() { Value[0] = SMA(5)[0]; }
AddChartIndicator() - https://ninjatrader.com/support/help...tindicator.htm
AddPlot() - https://ninjatrader.com/support/help...s/?addplot.htm
Values - https://ninjatrader.com/support/help...-us/values.htm
Please let us know if you have any questions.JimNinjaTrader Customer Service
-
Hello ninjo,
If you would like to integrate an indicator that performs custom rendering, that rendering code would have to be added to the parent indicator.
Essentially, indicators that are called in NinjaScript will simply calculate. To have an indicator display something, that (parent) indicator must either plot it or render it.
Please let us know if there is anything else we can do to help.JimNinjaTrader Customer Service
Comment
-
Jim at https://ninjatrader.com/support/foru...-anyone-fix-it I'm asking a similar question. I downloaded a fre indicator swingrays2 that draws ray off of swing highs and lows of a symbol. How can it be modified to draw them off of an indicator of my choice?
Comment
-
Hello ProfitPilgrim,
Are you referring to the Swingrays2 indicator on our EcoSystem User App Share that was posted by NinjaTrader_Paul? https://ninjatraderecosystem.com/use...ad/swingrays2/
The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.
This indicator uses Price Series (Open, High, Low and Close series) for data calculations and is not based off of the input of an indicator. The indicator could be modified to use Input instead of using High and Low, but you would have to include additional logic to hold the indicator's high and low prices for each developing bar when the script is set to calculate on price changes. The indicator can then be used with another indicator as input.
Below is an example for collecting indicator input High and Lows in a Series<double> using Calculate.OnPriceChange.
Code:private Series<double> IndiHigh, IndiLow; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "MyCustomIndicator"; Calculate = Calculate.OnPriceChange; } else if (State == State.DataLoaded) { IndiHigh = new Series<double>(this); IndiLow = new Series<double>(this); } } protected override void OnBarUpdate() { if (IsFirstTickOfBar) { IndiHigh[0] = IndiLow[0] = Input[0]; } else { if (Input[0] > IndiHigh[0]) IndiHigh[0] = Input[0]; if (Input[0] < IndiLow[0]) IndiLow[0] = Input[0]; } }
Please refer to the documentation pages below for more information on Calculate modes, Input, and Series<T> objects. This information is publicly available.
Calculate - https://ninjatrader.com/support/help.../calculate.htm
Input - https://ninjatrader.com/support/help...n-us/input.htm
Series<T> - https://ninjatrader.com/support/help...us/seriest.htm
Please let us know if you have any questions. If it interests you, we can also have someone reach out on NinjaScript Consulting services who could make any changes to the indicator at your request.JimNinjaTrader Customer Service
- Likes 1
Comment
-
-
Thanks to your sample code Jim we've modified SwingRays2 to draw from an indicator instead of the primary symbol. However, the rays only paint on panel 1. If the indicator is moved to panel two, or if it is originally assigned to panel 2 the rays still appear on panel 1. We can't find a parameter in Draw.Ray that assigns the ray to the indicator. We have "this" as the first parameter and believe that refers to the indicator class. The second problem we have is that if we check mark "keep broken lines" (code original to swingrays2) the indicator stops showing all ray it had created. Any suggestions on either of these problems. BTW we've combined the indicator code with the SwingRays2 code so we only have one indicator.
Comment
-
Hello ProfitPilgrim,
DrawOnPricePanel will determine if the indicator should draw objects on the price panel or the panel owned by the indicator. Using "this" represents "this NinjaScript" and would be used if you had a strategy which adds multiple indicators with multiple panels and you wanted the strategy to draw to those indicator panels.
DrawOnPricePanel documentation can be found here - https://ninjatrader.com/support/help...pricepanel.htm
Documentation for Draw.Ray so you can reference each parameter and each overload can be found here - https://ninjatrader.com/support/help...s/draw_ray.htm
Help Guide information is publicly available.
If you are able to create the issue with the original SwingRays2 script following some steps to hit the issue, we can let NinjaTrader_Paul know so he can take a look. If the issue is with your script and not in the original, I would suggest that you and your programmer review any changes made and to and compare the modifications against the original to troubleshoot further.
We look forward to being of further assistance.JimNinjaTrader Customer Service
- Likes 1
Comment
-
Originally posted by NinjaTrader_Jim View PostHello ninjo,
Thanks for your post.
AddChartIndicator is used for strategies only.
If you would like to add an indicator within an indicator and plot it, I would recommend instantiating the indicator as normal, and then to create another plot in the indicator for the SMA. Then within OnBarUpdate() assign the Value for that plot to be the value from the SMA indicator.
Code:protected override void OnStateChange() { if (State == State.SetDefaults) { AddPlot(Brushes.White, "MyAddedPlot"); } } protected override void OnBarUpdate() { Value[0] = SMA(5)[0]; }
AddChartIndicator() - https://ninjatrader.com/support/help...tindicator.htm
AddPlot() - https://ninjatrader.com/support/help...s/?addplot.htm
Values - https://ninjatrader.com/support/help...-us/values.htm
Please let us know if you have any questions.
How can I call the PriorDayOHLC stock indicator's OHLC values into my custom indicator?
Just for the Market Analyser — no need for plots.
I need to perform the following basic math formula:Prior day High - Prior Day Open
So far I've come up with that code:- public class Diff : Indicator
- {
- protected override void OnStateChange()
- {
- if (State == State.SetDefaults)
- {
- Description = @"Enter the description for your new custom Indicator here.";
- Name = "Diff";
- Calculate = Calculate.OnBarClose;
- 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(Brushes.White, "Diff");
- }
- else if (State == State.Configure)
- {
- }
- }
- protected override void OnBarUpdate()
- {
- if (CurrentBars[0] <= 55)
- return;
- if (BarsInProgress != 0)
- return;
- if (PriorDayOHLC.PriorDayHigh - PriorDayOHLC.PriorDayOpen == 0) // check for potential divide by zero
- {
- return; // don't plot the value
- }
- double PDOpen = PriorDayOHLC.PriorDayOpen;
- double PDHigh = PriorDayOHLC.PriorDayHigh;
- Value[0] = PDHigh - PDOpen;
- }
- #region Properties
- [Browsable(false)]
- [XmlIgnore]
- public Series<double> Diff
- {
- get { return Values[0]; }
- }
- #endregion
- }
Why those errors?
What's the simplest way to retrieve the Prior Day's Open and High?
Side question:When I paste code it does not preserves the formatting/ parenthesis indentation — and we need to squint to read the code.
How did you preserve the formatting in your paste above?
It would be great to update the forum to enable auto preservation of formatting when pasting for efficient reading time and less eyes strain.
Comment
-
Hello Cormick,
If you are having trouble writing syntax, try using the Strategy Builder to generate the syntax for you.
For example, Open the Strategy Builder, and without adding any conditions, click View Code. Then create a print that shows the result of the PriorDayOHLC High minus the PriorDayOHLC Open. Then click View Code again.
The code that is newly added may be implemented in your indicator.
We look forward to assisting.JimNinjaTrader Customer Service
Comment
-
Hi Jim,
Thanks for the answer and nice workaround advice.
I've generate and viewed the Strategy builder code.
Screenshots:
In the Indicator code (previously generated with the Indicator Wizard from the NinjaScript Editor),
here's no 'DataLoaded' section, versus on the Strategy builder code as below:
Code:else if (State == State.DataLoaded) { PriorDayOHLC1 = PriorDayOHLC(High); PriorDayOHLC2 = PriorDayOHLC(Open); PriorDayOHLC1.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC1.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC1.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC1.Plots[3].Brush = Brushes.SlateBlue; PriorDayOHLC2.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC2.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC2.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC2.Plots[3].Brush = Brushes.SlateBlue; AddChartIndicator(PriorDayOHLC1); AddChartIndicator(PriorDayOHLC2); } }
The Strategy Builder code:
EDIT1:
I've corrected Strategy Builder condition generated code as follows:
From:if (PriorDayOHLC1.PriorOpen[1] < PriorDayOHLC2.PriorOpen[1])
To:if (PriorDayOHLC1.PriorHigh[1] - PriorDayOHLC2.PriorOpen[1]
And Updated the indicator's code as follows:https://pastebin.com/m9Z2dAXp
Code:[LIST=1][*]public class Diff : Indicator[*]{[*]private PriorDayOHLC PriorDayOHLC1;[*]private PriorDayOHLC PriorDayOHLC2;[/LIST]
Code:[LIST=1][*]protected override void OnStateChange()[*]{[*]if (State == State.SetDefaults)[*]{[*]Description = @"Enter the description for your new custom Indicator here.";[*]Name = "Diff";[*]Calculate = Calculate.OnBarClose;[*]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(Brushes.White, "Diff");[*]}[*]else if (State == State.Configure)[*]{[*]}[*]}[/LIST]
Code:[LIST=1][*]protected override void OnBarUpdate()[*]{[*]if (CurrentBars[0] <= 55)[*]return;[*]if (BarsInProgress != 0)[*]return;[*]if (PriorDayOHLC1.PriorHigh[1] - PriorDayOHLC2.PriorOpen[1] == 0) // check for potential divide by zero[*]{[*]return; // don't plot the value[*]}[*]double PDHigh = PriorDayOHLC1.PriorHigh[1];[*]double PDOpen = PriorDayOHLC2.PriorOpen[1];[*]Value[0] = PDHigh - PDOpen;[*]}[/LIST]
Code:[LIST=1][*]#region Properties[*][Browsable(false)][*][XmlIgnore][*]public Series<double> Diff[*]{[*]get { return Values[0]; }[*]}[*]#endregion[*]}[/LIST]
Last edited by Cormick; 07-16-2021, 08:32 AM. Reason: Code edit Strategy Builder conditions to Indicator condition and rest
Comment
-
Hello Cormick,
The State.DataLoaded code instantiates the indicator and the OnBarUpdate code references the instantiated indicator.
If you uncheck "Plot on chart," you will be left with just the code necessary to read the indicator in NinjaScript code.
You are also creating the PriorDayOHLC indicator based off of High and Open PriceSeries, and are referencing the PriorOpen plot of those instantiated indicators. If you want to read the PriorOpen and PriorHigh, change the plot instead of changing the input Price Series.
The View Code result from my screenshot is attached, and this added code may be implemented in an indicator.JimNinjaTrader Customer Service
Comment
-
Hi Jim,
Thanks for the answer and points.
A short video of my steps:
I typed in your previous code in the Indicator wizard on the newly generated code (2nd part of the video above),
and it generated only a column of zeros in the output window as prints.
Your previous code:
Code:namespace NinjaTrader.NinjaScript.Indicators { public class HighMinusOpen1 : Indicator { private PriorDayOHLC PriorDayOHLC1; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "HighMinusOpen1"; Calculate = Calculate.OnBarClose; 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; } else if (State == State.Configure) { } else if (State == State.DataLoaded) { PriorDayOHLC1 = PriorDayOHLC(Close); } } protected override void OnBarUpdate() { if (CurrentBars[0] <= 1) return; if (BarsInProgress != 0) return; Print(Convert.ToString((PriorDayOHLC1.PriorHigh[0] - (PriorDayOHLC1.PriorOpen[0])) )); } } }
I don't understand why it doesn't print the Prior High - Prior Open subtraction result, nor see how to make it do so.
You also say:You are also creating the PriorDayOHLC indicator based off of High and Open PriceSeries, and are referencing the PriorOpen plot of those instantiated indicators. If you want to read the PriorOpen and PriorHigh, change the plot instead of changing the input Price Series.
I'm not sure of what you mean by changing the plot (Series?) instead of the input Price Series.
What is the Plot Series in the current context?
On my initial Strategy Builder generated code, the 'DataLoaded' snippet had some Plots code:
Code:else if (State == State.DataLoaded) { PriorDayOHLC1 = PriorDayOHLC(High); PriorDayOHLC2 = PriorDayOHLC(Open); PriorDayOHLC1.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC1.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC1.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC1.Plots[3].Brush = Brushes.SlateBlue; PriorDayOHLC2.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC2.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC2.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC2.Plots[3].Brush = Brushes.SlateBlue; AddChartIndicator(PriorDayOHLC1); AddChartIndicator(PriorDayOHLC2); } }
Aside:I don't understand also why there are 4 Plots for the High and 4 plots for the Open in the above snippet?Shouldn't there be only one of each?
Also in your code shared in the screenshot of post #13 above, the 'Dataloaded' snippet includes a (Close) parameter:
Code:else if (State == State.DataLoaded) { PriorDayOHLC1 = PriorDayOHLC(Close); }
What else am I missing?
How to do that the simplest way possible? Thanks for your help.
EDIT:
I added back theAddPlot(Brushes.White, "Diff");
and theValue[0] = (PriorDayOHLC1.PriorHigh[0] - (PriorDayOHLC1.PriorOpen[0]));
and the#region Properties
[Browsable(false)]
[XmlIgnore]
public Series<double> Diff
{
get { return Values[0]; }
}
#endregion
to the code:
Code:namespace NinjaTrader.NinjaScript.Indicators { public class HighMinusOpen1 : Indicator { private PriorDayOHLC PriorDayOHLC1; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "HighMinusOpen1"; Calculate = Calculate.OnBarClose; 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(Brushes.White, "Diff"); } else if (State == State.Configure) { } else if (State == State.DataLoaded) { PriorDayOHLC1 = PriorDayOHLC(Close); } } protected override void OnBarUpdate() { if (CurrentBars[0] <= 1) return; if (BarsInProgress != 0) return; Print(Convert.ToString((PriorDayOHLC1.PriorHigh[0] - (PriorDayOHLC1.PriorOpen[0])) )); Value[0] = (PriorDayOHLC1.PriorHigh[0] - (PriorDayOHLC1.PriorOpen[0])); } #region Properties [Browsable(false)] [XmlIgnore] public Series<double> Diff { get { return Values[0]; } } #endregion } }
What next to do?
Comment
-
Hello Cormick,
To get the full picture, I suggest first stepping back and setting up the print as I have in the Strategy Builder, and then to observe the result in the NinjaScript output window.
Code:PriorDayOHLC1 = PriorDayOHLC(High); PriorDayOHLC2 = PriorDayOHLC(Open);
Code:PriorDayOHLC1.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC1.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC1.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC1.Plots[3].Brush = Brushes.SlateBlue; PriorDayOHLC2.Plots[0].Brush = Brushes.SteelBlue; PriorDayOHLC2.Plots[1].Brush = Brushes.DarkCyan; PriorDayOHLC2.Plots[2].Brush = Brushes.Crimson; PriorDayOHLC2.Plots[3].Brush = Brushes.SlateBlue; AddChartIndicator(PriorDayOHLC1); AddChartIndicator(PriorDayOHLC2);
Once you get the same code generated with the print, test the strategy and observe the value in the NinjaScript output window. Then implement that code in an indicator and test the same.
At this point, you will have seen how you can generate the syntax, implement in an indicator, and how you can view the result. The next step is adding a plot to the indicator and assigning the value to the plot instead of printing it. (This will allow the Market Analyzer to read the indicator.) The documentation below describes how you may add plots and assign values to plots.
AddPlot - https://ninjatrader.com/support/help...8/?addplot.htm
After this you will be done setting up the indicator. You can then add it to the Market Analyzer as an indicator column, and ensure that you have your plot selected in the Market Analyzer Column.Last edited by NinjaTrader_Jim; 07-16-2021, 12:45 PM.JimNinjaTrader Customer Service
- Likes 1
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by rbeckmann05, Yesterday, 06:48 PM
|
1 response
12 views
0 likes
|
Last Post
by bltdavid
Today, 05:43 AM
|
||
Started by llanqui, Today, 03:53 AM
|
0 responses
6 views
0 likes
|
Last Post
by llanqui
Today, 03:53 AM
|
||
Started by burtoninlondon, Today, 12:38 AM
|
0 responses
10 views
0 likes
|
Last Post Today, 12:38 AM | ||
Started by AaronKoRn, Yesterday, 09:49 PM
|
0 responses
15 views
0 likes
|
Last Post
by AaronKoRn
Yesterday, 09:49 PM
|
||
Started by carnitron, Yesterday, 08:42 PM
|
0 responses
11 views
0 likes
|
Last Post
by carnitron
Yesterday, 08:42 PM
|
Comment