You would need to use prints to know why the value is the way it is. I can't answer that from a picture.
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
SMA with custome data series [INPUT] assembly missing
Collapse
X
-
I now want to use close price for two DataSeries, GC 12-23 and SI 12-23.
And Print returns
Inst1 Close[0][0]: 1943.1 //GC 12-23 price
Inst2 Close[1][0]: 1943.1 //GC 12-23 price, should be SI 12-23
Price Difference[0]: 0
What is wrong with my code?
Code:namespace NinjaTrader.NinjaScript.Indicators { public class GC2 : Indicator { //private int smaPeriod = 1; // Default SMA period private Series<double> Inst1SMA; private Series<double> Inst2SMA; private Series<double> PriceDifferenceSeries; // Declare properties private double multip1 = 1.0; // Default value for Multip1 private double multip2 = 1.0; // Default value for Multip2 protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "GC2"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = false; DrawVerticalGridLines = false; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay; IsSuspendedWhileInactive = true; //smaPeriod = 1; AddPlot(Brushes.Magenta, "PriceDifference"); // Set default values here multip1 = 1.0; multip2 = 1.0; } else if (State == State.Configure) { // Add two data Series AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, 60, Data.MarketDataType.Last); AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, 60, Data.MarketDataType.Last); // Initialize the Series for SMA(Simply Close) Inst1SMA = new Series<double>(this); Inst2SMA = new Series<double>(this); PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite); } } protected override void OnBarUpdate() { // Calculate the SMA-based difference between the instruments if (BarsInProgress == 0) { double inst1Close = Closes[0][0]; double inst2Close = Closes[1][0]; double priceDifference = (inst1Close * multip1) - (inst2Close * multip2); // Print the values for monitoring Print("Inst1 Close[0][0]: " + inst1Close); Print("Inst2 Close[1][0]: " + inst2Close); Print("Price Difference[0]: " + priceDifference); // Set the Value for plotting Value[0] = priceDifference; // Print the price for PriceDifference Print("Price Difference Value[0]: " + Value[0]); } }
Comment
-
Hello.
I found the value for 2 series and difference is working in Output screen. But if I apply in chart, databox PriceDifference screen shows n/a and line are not shown.
Here is the latest, What is wrong with below PriceDifference Assignment to Addplot to draw the line?
Code:public class GC2 : Indicator { private Series<double> Inst1SMA; private Series<double> Inst2SMA; private Series<double> PriceDifferenceSeries; // Declare properties with unique names private double _multip1 = 1.0; private double _multip2 = 1.0; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "GC2"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = false; DrawVerticalGridLines = false; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay; IsSuspendedWhileInactive = true; AddPlot(new Stroke(Brushes.Magenta, 3), PlotStyle.Line,"PriceDifference"); // Set default values for properties _multip1 = 1.0; _multip2 = 60.0; } else if (State == State.Configure) { // Add two data Series AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last); AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last); // Initialize the Series Inst1SMA = new Series<double>(this); Inst2SMA = new Series<double>(this); PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite); } } protected override void OnBarUpdate() { if (BarsInProgress == 0) { double inst1Close = Closes[1][0]; // Use 1 to access "GC 12-23" double inst2Close = Closes[2][0]; // Use 2 to access "SI 12-23" double priceDifference = (inst1Close * _multip1) - (inst2Close * _multip2); // Print the values for monitoring Print("Inst1 Close[0][0]: " + inst1Close); Print("Inst2 Close[0][0]: " + inst2Close); Print("Price Difference[0]: " + priceDifference); // Set the Value for plotting PriceDifferenceSeries[0] = priceDifference; // Print the price for PriceDifference Print("Price Difference Value[0]: " + PriceDifferenceSeries[0]); } } [HASHTAG="t3322"]region[/HASHTAG] Properties [Range(1, double.MaxValue)] [Display(Name = "Multip1", Order = 3, GroupName = "Parameters")] public double Multip1 { get { return _multip1; } set { _multip1 = value; } } [NinjaScriptProperty] [Range(1, double.MaxValue)] [Display(Name = "Multip2", Order = 4, GroupName = "Parameters")] public double Multip2 { get { return _multip2; } set { _multip2 = value; } } #endregion }
Last edited by Marble; 09-08-2023, 11:24 AM.
Comment
-
Hi Jesse,
I see. I have added below and worked.
Value[0] = priceDifference;
I have reviewed the code and found that multp1 is not mentioned NinjaScript generated code.
Assuming this would cause multip1 input not available in strategy. How can I generated code show multip1?
Code:[HASHTAG="t3322"]region[/HASHTAG] NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private GC2[] cacheGC2; public GC2 GC2(double multip2) { return GC2(Input, multip2); } public GC2 GC2(ISeries<double> input, double multip2) { if (cacheGC2 != null) for (int idx = 0; idx < cacheGC2.Length; idx++) if (cacheGC2[idx] != null && cacheGC2[idx].Multip2 == multip2 && cacheGC2[idx].EqualsInput(input)) return cacheGC2[idx]; return CacheIndicator<GC2>(new GC2(){ Multip2 = multip2 }, input, ref cacheGC2); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.GC2 GC2(double multip2) { return indicator.GC2(Input, multip2); } public Indicators.GC2 GC2(ISeries<double> input , double multip2) { return indicator.GC2(input, multip2); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.GC2 GC2(double multip2) { return indicator.GC2(Input, multip2); } public Indicators.GC2 GC2(ISeries<double> input , double multip2) { return indicator.GC2(input, multip2); } } } #endregion
Comment
-
Yes, I am aware, Both multip1 and multip2 are set as Public in Property region. But only multip2 is generated under do not edit region,
These are always declared together. Why only multip2 is generated for public accessable and how can I have multip1 the same way.
If I edit do not generate, if would just disregarded when compiled/
Code:namespace NinjaTrader.NinjaScript.Indicators { public class GC2 : Indicator { private Series<double> Inst1SMA; private Series<double> Inst2SMA; private Series<double> PriceDifferenceSeries; // Declare properties with unique names private double _multip1 = 1.0; private double _multip2 = 1.0; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "GC2"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = false; DrawVerticalGridLines = false; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay; IsSuspendedWhileInactive = true; AddPlot(new Stroke(Brushes.Magenta, 3), PlotStyle.Line,"PriceDifference"); // Set default values for properties _multip1 = 1.0; _multip2 = 60.0; } else if (State == State.Configure) { // Add two data Series AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last); AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last); // Initialize the Series Inst1SMA = new Series<double>(this); Inst2SMA = new Series<double>(this); PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite); } } protected override void OnBarUpdate() { if (BarsInProgress == 0) { double inst1Close = Closes[1][0]; // Use 1 to access "GC 12-23" double inst2Close = Closes[2][0]; // Use 2 to access "SI 12-23" double priceDifference = (inst1Close * _multip1) - (inst2Close * _multip2); // Print the values for monitoring Print("Inst1 Close[0][0]: " + inst1Close); Print("Inst2 Close[0][0]: " + inst2Close); Print("Price Difference[0]: " + priceDifference); // Set the Value for plotting PriceDifferenceSeries[0] = priceDifference; // Plot the price for PriceDifferenceSeries Value[0] = priceDifference; // Print the price for PriceDifference Print("Price Difference Value[0]: " + PriceDifferenceSeries[0]); } } [HASHTAG="t3322"]region[/HASHTAG] Properties [Range(1, double.MaxValue)] [Display(Name = "Multip1", Order = 3, GroupName = "Parameters")] public double Multip1 { get { return _multip1; } set { _multip1 = value; } } [NinjaScriptProperty] [Range(1, double.MaxValue)] [Display(Name = "Multip2", Order = 4, GroupName = "Parameters")] public double Multip2 { get { return _multip2; } set { _multip2 = value; } } #endregion } } [HASHTAG="t3322"]region[/HASHTAG] NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private GC2[] cacheGC2; public GC2 GC2(double multip2) { return GC2(Input, multip2); } public GC2 GC2(ISeries<double> input, double multip2) { if (cacheGC2 != null) for (int idx = 0; idx < cacheGC2.Length; idx++) if (cacheGC2[idx] != null && cacheGC2[idx].Multip2 == multip2 && cacheGC2[idx].EqualsInput(input)) return cacheGC2[idx]; return CacheIndicator<GC2>(new GC2(){ Multip2 = multip2 }, input, ref cacheGC2); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.GC2 GC2(double multip2) { return indicator.GC2(Input, multip2); } public Indicators.GC2 GC2(ISeries<double> input , double multip2) { return indicator.GC2(input, multip2); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.GC2 GC2(double multip2) { return indicator.GC2(Input, multip2); } public Indicators.GC2 GC2(ISeries<double> input , double multip2) { return indicator.GC2(input, multip2); } } } #endregion
Last edited by Marble; 09-08-2023, 12:47 PM.
Comment
-
The line and calculation seems to be working fine under if the chart is for period= second (when loaded, it is usually 60 second), but but if chart switched to minute or else, does not work.
control log error is "accessing in an index with a value out of range”
I have updated AddBarSeries to match primary BarsPeriod as below. But still, the line dissapears assuming the BarPeriod the issue. but no error in compiling but does not work.
How can I set the AddBarSeries DataBarsPeriodType to align primary chart period type?
Code:// Access the current chart's BarsPeriodType and use it for data series BarsPeriodType currentBarsPeriodType = BarsArray[0].BarsPeriod.BarsPeriodType; // Add two data Series AddDataSeries("GC 12-23", currentBarsPeriodType, BarsPeriod.Value, Data.MarketDataType.Last); AddDataSeries("SI 12-23", currentBarsPeriodType, BarsPeriod.Value, Data.MarketDataType.Last); //AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);
Comment
-
Hello Marble,
AddDataSeries needs to be hard coded, it does not have a overload set to match the primary bars type. You would need to type in the values you want, this is mentioned in the help guide:
Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input). Attempting to add a data series dynamically is NOT guaranteed and therefore should be avoided.
After making sure no variables are being used with AddDataSeries you can then go through your logic to see which line is having an error in that use case so that you can correct it or add error handling to prevent the error.JesseNinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by halgo_boulder, 04-20-2024, 08:44 AM
|
2 responses
21 views
0 likes
|
Last Post Today, 09:41 AM | ||
Started by mishhh, 05-25-2010, 08:54 AM
|
19 responses
6,189 views
0 likes
|
Last Post
by rene69851
Today, 09:29 AM
|
||
Started by gwenael, Today, 09:29 AM
|
0 responses
5 views
0 likes
|
Last Post
by gwenael
Today, 09:29 AM
|
||
Started by Karado58, 11-26-2012, 02:57 PM
|
8 responses
14,830 views
0 likes
|
Last Post Today, 09:09 AM | ||
Started by Option Whisperer, Today, 09:05 AM
|
0 responses
2 views
0 likes
|
Last Post Today, 09:05 AM |
Comment